From 74b4d89b0d659c98033f8c98b28e7a5cadd6890a Mon Sep 17 00:00:00 2001 From: Daniel Imbert Date: Fri, 7 Aug 2026 20:18:11 -0400 Subject: [PATCH 01/11] fix(core1): adapt atomic stock values to Appwrite Double API --- .../product/data/repository/ProductNetRepositoryImpl.kt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/com/elitec/alejotaller/feature/product/data/repository/ProductNetRepositoryImpl.kt b/app/src/main/java/com/elitec/alejotaller/feature/product/data/repository/ProductNetRepositoryImpl.kt index 9abcf67..e747ef8 100644 --- a/app/src/main/java/com/elitec/alejotaller/feature/product/data/repository/ProductNetRepositoryImpl.kt +++ b/app/src/main/java/com/elitec/alejotaller/feature/product/data/repository/ProductNetRepositoryImpl.kt @@ -41,8 +41,8 @@ class ProductNetRepositoryImpl( collectionId = BuildConfig.PRODUCT_TABLE_ID, documentId = productId, attribute = "reserved", - value = quantity, - max = maxReserved + value = quantity.toDouble(), + max = maxReserved.toDouble() ) return response.toProductDto() } @@ -55,8 +55,8 @@ class ProductNetRepositoryImpl( collectionId = BuildConfig.PRODUCT_TABLE_ID, documentId = productId, attribute = "reserved", - value = quantity, - min = 0 + value = quantity.toDouble(), + min = 0.0 ) return response.toProductDto() } From b6c1c2e39376f10e70cd17613fa145a7aebf4869 Mon Sep 17 00:00:00 2001 From: Daniel Imbert Date: Fri, 7 Aug 2026 20:18:38 -0400 Subject: [PATCH 02/11] refactor(shared-data): migrate sale mapper to Appwrite Row --- .../data/feature/sale/data/mapper/Document.toSaleDto.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/shared-data/src/main/java/com/elitec/shared/data/feature/sale/data/mapper/Document.toSaleDto.kt b/shared-data/src/main/java/com/elitec/shared/data/feature/sale/data/mapper/Document.toSaleDto.kt index 3b3cd24..f79aa8e 100644 --- a/shared-data/src/main/java/com/elitec/shared/data/feature/sale/data/mapper/Document.toSaleDto.kt +++ b/shared-data/src/main/java/com/elitec/shared/data/feature/sale/data/mapper/Document.toSaleDto.kt @@ -3,7 +3,7 @@ package com.elitec.shared.data.feature.sale.data.mapper import com.elitec.shared.data.feature.sale.data.dto.SaleDto import com.elitec.shared.sale.feature.sale.domain.entity.Currency import com.elitec.shared.sale.feature.sale.domain.entity.SaleItem -import io.appwrite.models.Document +import io.appwrite.models.Row import kotlinx.datetime.LocalDate import kotlinx.serialization.json.Json import kotlinx.serialization.json.JsonArray @@ -12,7 +12,7 @@ import kotlinx.serialization.json.JsonObject import kotlinx.serialization.json.JsonPrimitive import kotlinx.serialization.json.intOrNull -fun Document>.toSaleDto(): SaleDto = +fun Row>.toSaleDto(): SaleDto = SaleDto( id = id, date = data["date"].toLocalDate(), From 548b854c4a27d2be8d8671f3a086f5f5e07911d1 Mon Sep 17 00:00:00 2001 From: Daniel Imbert Date: Fri, 7 Aug 2026 20:19:00 -0400 Subject: [PATCH 03/11] refactor(shared-data): migrate sale repository to TablesDB rows --- .../data/repository/SaleNetRepositoryImpl.kt | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/shared-data/src/main/java/com/elitec/shared/data/feature/sale/data/repository/SaleNetRepositoryImpl.kt b/shared-data/src/main/java/com/elitec/shared/data/feature/sale/data/repository/SaleNetRepositoryImpl.kt index 00231da..74a888a 100644 --- a/shared-data/src/main/java/com/elitec/shared/data/feature/sale/data/repository/SaleNetRepositoryImpl.kt +++ b/shared-data/src/main/java/com/elitec/shared/data/feature/sale/data/repository/SaleNetRepositoryImpl.kt @@ -6,30 +6,30 @@ import com.elitec.shared.data.feature.sale.data.mapper.toSaleDto import com.elitec.shared.data.infraestructure.core.data.config.SaleRemoteConfig import io.appwrite.ID import io.appwrite.Query -import io.appwrite.services.Databases +import io.appwrite.services.TablesDB import kotlinx.serialization.json.Json class SaleNetRepositoryImpl( - private val netDB: Databases, + private val netDB: TablesDB, private val config: SaleRemoteConfig ): SaleNetRepository { override suspend fun getAll(userId: String): List { Log.i(TAG, "event=sale_net_get_all_start userId=$userId collection=${config.saleCollectionId}") - val response = netDB.listDocuments( + val response = netDB.listRows( databaseId = config.databaseId, - collectionId = config.saleCollectionId, + tableId = config.saleCollectionId, queries = listOf(Query.equal("user_id", userId)) ) - Log.i(TAG, "event=sale_net_get_all_success userId=$userId count=${response.documents.size}") - return response.documents.map { document -> document.toSaleDto() } + Log.i(TAG, "event=sale_net_get_all_success userId=$userId count=${response.rows.size}") + return response.rows.map { row -> row.toSaleDto() } } override suspend fun getById(itemId: String): SaleDto { Log.i(TAG, "event=sale_net_get_by_id_start saleId=$itemId collection=${config.saleCollectionId}") - val response = netDB.getDocument( + val response = netDB.getRow( databaseId = config.databaseId, - collectionId = config.saleCollectionId, - documentId = itemId + tableId = config.saleCollectionId, + rowId = itemId ) Log.i(TAG, "event=sale_net_get_by_id_success saleId=$itemId") return response.toSaleDto() @@ -39,13 +39,13 @@ class SaleNetRepositoryImpl( val normalizedQuery = query.trim() if (normalizedQuery.isBlank()) return emptyList() - val response = netDB.listDocuments( + val response = netDB.listRows( databaseId = config.databaseId, - collectionId = config.saleCollectionId, + tableId = config.saleCollectionId, queries = listOf(Query.limit(limit)) ) - return response.documents + return response.rows .map { it.toSaleDto() } .filter { sale -> when (field.uppercase()) { @@ -61,10 +61,10 @@ class SaleNetRepositoryImpl( override suspend fun save(item: SaleDto) { val resolvedId = item.id.ifBlank { ID.unique() } Log.i(TAG, "event=sale_net_save_start saleId=$resolvedId userId=${item.userId} verified=${item.verified}") - netDB.createDocument( + netDB.createRow( databaseId = config.databaseId, - collectionId = config.saleCollectionId, - documentId = resolvedId, + tableId = config.saleCollectionId, + rowId = resolvedId, data = item.toAppwriteData() ) Log.i(TAG, "event=sale_net_save_success saleId=$resolvedId") @@ -73,10 +73,10 @@ class SaleNetRepositoryImpl( override suspend fun upsert(item: SaleDto) { if (item.id.isBlank()) return Log.i(TAG, "event=sale_net_upsert_start saleId=${item.id} userId=${item.userId} verified=${item.verified}") - netDB.updateDocument( + netDB.updateRow( databaseId = config.databaseId, - collectionId = config.saleCollectionId, - documentId = item.id, + tableId = config.saleCollectionId, + rowId = item.id, data = item.toAppwriteData() ) Log.i(TAG, "event=sale_net_upsert_updated saleId=${item.id}") From 2aa2dfe2c9b3a343894ba5f475a3e418821615f1 Mon Sep 17 00:00:00 2001 From: Daniel Imbert Date: Fri, 7 Aug 2026 20:19:11 -0400 Subject: [PATCH 04/11] refactor(app): provide TablesDB for sale repository --- .../alejotaller/infraestructure/di/infrastructureDiModule.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/elitec/alejotaller/infraestructure/di/infrastructureDiModule.kt b/app/src/main/java/com/elitec/alejotaller/infraestructure/di/infrastructureDiModule.kt index 72f72f9..7b3bd9b 100644 --- a/app/src/main/java/com/elitec/alejotaller/infraestructure/di/infrastructureDiModule.kt +++ b/app/src/main/java/com/elitec/alejotaller/infraestructure/di/infrastructureDiModule.kt @@ -22,6 +22,7 @@ import io.appwrite.Client import io.appwrite.services.Account import io.appwrite.services.Databases import io.appwrite.services.Storage +import io.appwrite.services.TablesDB import io.ktor.client.HttpClient import io.ktor.client.engine.android.Android import io.ktor.client.plugins.contentnegotiation.ContentNegotiation @@ -45,6 +46,7 @@ val infrastructureModule = module { .setSelfSigned(false) } single { Databases(get()) } + single { TablesDB(get()) } single { Account(get()) } single { Storage(get()) } single { @@ -61,7 +63,7 @@ val infrastructureModule = module { klass = AppBD::class.java, name = "app_database" ) - .addMigrations(*AppBDMigrations.ALL) // ✅ Migraciones registradas + .addMigrations(*AppBDMigrations.ALL) .build() } From 9d02e17a318fbeb61de03f0acf15481d29d3ce66 Mon Sep 17 00:00:00 2001 From: Daniel Imbert Date: Fri, 7 Aug 2026 20:19:25 -0400 Subject: [PATCH 05/11] docs(core1): log CI compilation and Appwrite API corrections --- .../2026-08-07-GPT-5.6-Luna-core1-ci-fix.md | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 .roadmap/Core 1/changes/AgentsLogs/2026-08-07-GPT-5.6-Luna-core1-ci-fix.md diff --git a/.roadmap/Core 1/changes/AgentsLogs/2026-08-07-GPT-5.6-Luna-core1-ci-fix.md b/.roadmap/Core 1/changes/AgentsLogs/2026-08-07-GPT-5.6-Luna-core1-ci-fix.md new file mode 100644 index 0000000..d3b062b --- /dev/null +++ b/.roadmap/Core 1/changes/AgentsLogs/2026-08-07-GPT-5.6-Luna-core1-ci-fix.md @@ -0,0 +1,26 @@ +# Core 1 CI correction log + +Date: 2026-08-07 +model: GPT-5.6 Luna +Route: app/src/main/java/com/elitec/alejotaller/feature/product/data/repository/ProductNetRepositoryImpl.kt +Description: Ajusté las operaciones atómicas de stock de Core 1 para adaptar los valores enteros del dominio (`quantity`, `maxReserved`) al contrato `Double?` exigido por el SDK Android de Appwrite. Se mantuvo el dominio de inventario como cantidades enteras y el cambio se limita a la frontera de infraestructura. `incrementReserved` usa `toDouble()` para `value` y `max`, mientras `decrementReserved` usa `toDouble()` para `value` y `0.0` como mínimo. El objetivo es resolver el error de compilación `Int` vs `Double?` reportado por `:app:compileDebugKotlin` sin alterar la semántica de stock. + +Date: 2026-08-07 +model: GPT-5.6 Luna +Route: shared-data/src/main/java/com/elitec/shared/data/feature/sale/data/mapper/Document.toSaleDto.kt +Description: Migré el mapper de ventas de `Document>` a `Row>` para eliminar la dependencia del modelo obsoleto de Databases y permitir la migración del repositorio de ventas a TablesDB. Se conservaron las reglas existentes de conversión de fecha, monto, productos, estado de compra, usuario y `stockHoldApplied`. + +Date: 2026-08-07 +model: GPT-5.6 Luna +Route: shared-data/src/main/java/com/elitec/shared/data/feature/sale/data/repository/SaleNetRepositoryImpl.kt +Description: Migré las operaciones de ventas de la API obsoleta de Appwrite Databases (`listDocuments`, `getDocument`, `createDocument`, `updateDocument`) a `TablesDB` (`listRows`, `getRow`, `createRow`, `updateRow`). El cambio conserva el mismo flujo de dominio, filtros, IDs y payloads, pero utiliza el modelo actual de Rows recomendado por Appwrite. Esto elimina los warnings de obsolescencia observados durante `:shared-data:compileDebugKotlin`. + +Date: 2026-08-07 +model: GPT-5.6 Luna +Route: app/src/main/java/com/elitec/alejotaller/infraestructure/di/infrastructureDiModule.kt +Description: Registré `TablesDB` como dependencia de infraestructura de Appwrite para que `SaleNetRepositoryImpl` pueda consumir el servicio moderno sin eliminar `Databases`, ya que otras partes de Core 1 todavía pueden depender de esa API. La migración se mantiene acotada al repositorio de ventas. + +Date: 2026-08-07 +model: GPT-5.6 Luna +Route: .roadmap/Core 1/changes/AgentsLogs/2026-08-07-GPT-5.6-Luna-core1-ci-fix.md +Description: Creé este registro para dejar trazabilidad de la corrección solicitada después del fallo de CI. La corrección se realizó sobre la rama `fix/core1-ci-stock-and-deprecations`, creada desde `master`, y está destinada a validación mediante Pull Request antes de cualquier integración en producción. From 3ce054818c95e4226e2116b8181d10b4ba49a1c5 Mon Sep 17 00:00:00 2001 From: Daniel Imbert Date: Fri, 7 Aug 2026 20:19:42 -0400 Subject: [PATCH 06/11] refactor(web): provide TablesDB for Appwrite row APIs --- web/src/core/infrastructure/di/appwrite.config.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web/src/core/infrastructure/di/appwrite.config.ts b/web/src/core/infrastructure/di/appwrite.config.ts index 8d7782a..1be4a7d 100644 --- a/web/src/core/infrastructure/di/appwrite.config.ts +++ b/web/src/core/infrastructure/di/appwrite.config.ts @@ -1,4 +1,4 @@ -import {Client, Databases, Storage, Account, Functions} from "appwrite" +import {Client, TablesDB, Storage, Account, Functions} from "appwrite" import {ENV} from "../env"; const client = new Client() @@ -13,7 +13,7 @@ if (ENV.appwriteEndpoint && ENV.appwriteProjectId) { ); } -export const databases = new Databases(client) +export const tablesDB = new TablesDB(client) export const storage = new Storage(client) export const account = new Account(client) export const functions = new Functions(client) From 6aa8a397ccb2818c9a99a307759cb45718866e58 Mon Sep 17 00:00:00 2001 From: Daniel Imbert Date: Fri, 7 Aug 2026 20:19:52 -0400 Subject: [PATCH 07/11] fix(web): preserve Databases while adding TablesDB service --- web/src/core/infrastructure/di/appwrite.config.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/web/src/core/infrastructure/di/appwrite.config.ts b/web/src/core/infrastructure/di/appwrite.config.ts index 1be4a7d..4e195fa 100644 --- a/web/src/core/infrastructure/di/appwrite.config.ts +++ b/web/src/core/infrastructure/di/appwrite.config.ts @@ -1,4 +1,4 @@ -import {Client, TablesDB, Storage, Account, Functions} from "appwrite" +import {Client, Databases, TablesDB, Storage, Account, Functions} from "appwrite" import {ENV} from "../env"; const client = new Client() @@ -13,6 +13,7 @@ if (ENV.appwriteEndpoint && ENV.appwriteProjectId) { ); } +export const databases = new Databases(client) export const tablesDB = new TablesDB(client) export const storage = new Storage(client) export const account = new Account(client) From 62469b1bd3923b9809bf6a9aeb8c1efd5ebbd37a Mon Sep 17 00:00:00 2001 From: Daniel Imbert Date: Fri, 7 Aug 2026 20:20:01 -0400 Subject: [PATCH 08/11] refactor(web): migrate sale repository to TablesDB rows --- .../data/repository/sale.net.repository.ts | 78 +++++++++---------- 1 file changed, 39 insertions(+), 39 deletions(-) diff --git a/web/src/core/feature/sale/data/repository/sale.net.repository.ts b/web/src/core/feature/sale/data/repository/sale.net.repository.ts index b2fc388..c52dd91 100644 --- a/web/src/core/feature/sale/data/repository/sale.net.repository.ts +++ b/web/src/core/feature/sale/data/repository/sale.net.repository.ts @@ -1,9 +1,9 @@ import type { SaleDTO } from "../dto/SaleDTO"; -import { type Databases, ID, Query } from "appwrite"; +import { type TablesDB, ID, Query } from "appwrite"; import type { Models } from "appwrite"; import { ENV } from "../../../../infrastructure/env"; -const COLLECTION_ID = "sale"; +const TABLE_ID = "sale"; function stripMeta(data: Record): Record { const clean: Record = {}; @@ -16,7 +16,7 @@ function stripMeta(data: Record): Record { } export class SaleNetRepository { - constructor(private databases: Databases) {} + constructor(private tablesDB: TablesDB) {} private get databaseId(): string { const id = ENV.databaseId; @@ -25,60 +25,60 @@ export class SaleNetRepository { } async getAll(): Promise { - const response = await this.databases.listDocuments( - this.databaseId, - COLLECTION_ID - ) + const response = await this.tablesDB.listRows({ + databaseId: this.databaseId, + tableId: TABLE_ID, + }); - return response.documents + return response.rows as unknown as SaleDTO[]; } async create( - data: Omit | Record + data: Omit | Record ): Promise { const payload = stripMeta(data as Record); - return await this.databases.createDocument( - this.databaseId, - COLLECTION_ID, - ID.unique(), - payload - ) + return await this.tablesDB.createRow({ + databaseId: this.databaseId, + tableId: TABLE_ID, + rowId: ID.unique(), + data: payload, + }) as unknown as SaleDTO; } async getByUser(userId: string): Promise { - const response = await this.databases.listDocuments( - this.databaseId, - COLLECTION_ID, - [Query.equal("user_id", userId)] - ) + const response = await this.tablesDB.listRows({ + databaseId: this.databaseId, + tableId: TABLE_ID, + queries: [Query.equal("user_id", userId)], + }); - return response.documents + return response.rows as unknown as SaleDTO[]; } async updateVerified(id: string, verified: string): Promise { - return await this.databases.updateDocument( - this.databaseId, - COLLECTION_ID, - id, - { buy_state: verified } - ); + return await this.tablesDB.updateRow({ + databaseId: this.databaseId, + tableId: TABLE_ID, + rowId: id, + data: { buy_state: verified }, + }) as unknown as SaleDTO; } async updateDeliveryType(id: string, deliveryType: string): Promise { - return await this.databases.updateDocument( - this.databaseId, - COLLECTION_ID, - id, - { delivery_type: deliveryType } - ); + return await this.tablesDB.updateRow({ + databaseId: this.databaseId, + tableId: TABLE_ID, + rowId: id, + data: { delivery_type: deliveryType }, + }) as unknown as SaleDTO; } async updateStockHoldApplied(id: string, value: boolean): Promise { - return await this.databases.updateDocument( - this.databaseId, - COLLECTION_ID, - id, - { stock_hold_applied: value } - ); + return await this.tablesDB.updateRow({ + databaseId: this.databaseId, + tableId: TABLE_ID, + rowId: id, + data: { stock_hold_applied: value }, + }) as unknown as SaleDTO; } } From fa6c6fb428c44298a3278e733edbafe655110ab4 Mon Sep 17 00:00:00 2001 From: Daniel Imbert Date: Fri, 7 Aug 2026 20:20:13 -0400 Subject: [PATCH 09/11] fix(web): use unconstrained TablesDB row responses --- .../sale/data/repository/sale.net.repository.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/web/src/core/feature/sale/data/repository/sale.net.repository.ts b/web/src/core/feature/sale/data/repository/sale.net.repository.ts index c52dd91..d9166c6 100644 --- a/web/src/core/feature/sale/data/repository/sale.net.repository.ts +++ b/web/src/core/feature/sale/data/repository/sale.net.repository.ts @@ -25,7 +25,7 @@ export class SaleNetRepository { } async getAll(): Promise { - const response = await this.tablesDB.listRows({ + const response = await this.tablesDB.listRows({ databaseId: this.databaseId, tableId: TABLE_ID, }); @@ -37,7 +37,7 @@ export class SaleNetRepository { data: Omit | Record ): Promise { const payload = stripMeta(data as Record); - return await this.tablesDB.createRow({ + return await this.tablesDB.createRow({ databaseId: this.databaseId, tableId: TABLE_ID, rowId: ID.unique(), @@ -46,7 +46,7 @@ export class SaleNetRepository { } async getByUser(userId: string): Promise { - const response = await this.tablesDB.listRows({ + const response = await this.tablesDB.listRows({ databaseId: this.databaseId, tableId: TABLE_ID, queries: [Query.equal("user_id", userId)], @@ -56,7 +56,7 @@ export class SaleNetRepository { } async updateVerified(id: string, verified: string): Promise { - return await this.tablesDB.updateRow({ + return await this.tablesDB.updateRow({ databaseId: this.databaseId, tableId: TABLE_ID, rowId: id, @@ -65,7 +65,7 @@ export class SaleNetRepository { } async updateDeliveryType(id: string, deliveryType: string): Promise { - return await this.tablesDB.updateRow({ + return await this.tablesDB.updateRow({ databaseId: this.databaseId, tableId: TABLE_ID, rowId: id, @@ -74,7 +74,7 @@ export class SaleNetRepository { } async updateStockHoldApplied(id: string, value: boolean): Promise { - return await this.tablesDB.updateRow({ + return await this.tablesDB.updateRow({ databaseId: this.databaseId, tableId: TABLE_ID, rowId: id, From 5843e96ef5a2c7e9bca8960d0a33c8e1aef6c364 Mon Sep 17 00:00:00 2001 From: Daniel Imbert Date: Fri, 7 Aug 2026 20:20:23 -0400 Subject: [PATCH 10/11] refactor(web): inject TablesDB into sale repository --- web/src/core/feature/sale/di/sale.container.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web/src/core/feature/sale/di/sale.container.ts b/web/src/core/feature/sale/di/sale.container.ts index 3900710..1ff0006 100644 --- a/web/src/core/feature/sale/di/sale.container.ts +++ b/web/src/core/feature/sale/di/sale.container.ts @@ -10,9 +10,9 @@ import { SessionSaleNotificationUserProvider } from "../data/repository/SessionS import { TelegramNotificatorImpl } from "../data/repository/TelegramNotificatorImpl"; import {productContainer} from "../../product/di/product.container"; -const netDatabases= infrastructureContainer.appwrite.databases +const netTablesDB = infrastructureContainer.appwrite.tablesDB -const saleNetRepository = new SaleNetRepository(netDatabases) +const saleNetRepository = new SaleNetRepository(netTablesDB) const saleOfflineFirstRepository = new SaleOfflineFirstRepository(saleNetRepository) const saleNotificationUserProvider = new SessionSaleNotificationUserProvider( () => infrastructureContainer.appwrite.account.get() From 8dac3d9deb3dd3e9b9bc9237b6aadd1ab00df2e4 Mon Sep 17 00:00:00 2001 From: Daniel Imbert Date: Fri, 7 Aug 2026 20:20:30 -0400 Subject: [PATCH 11/11] fix(web): expose TablesDB through infrastructure container --- web/src/core/infrastructure/di/infrastructure.container.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/web/src/core/infrastructure/di/infrastructure.container.ts b/web/src/core/infrastructure/di/infrastructure.container.ts index f9ac999..fbbcf27 100644 --- a/web/src/core/infrastructure/di/infrastructure.container.ts +++ b/web/src/core/infrastructure/di/infrastructure.container.ts @@ -1,4 +1,4 @@ -import {account, client, databases, functions, storage} from "./appwrite.config"; +import {account, client, databases, functions, storage, tablesDB} from "./appwrite.config"; import {db} from "./dexie.db"; import {authService} from "./auth.service"; @@ -6,6 +6,7 @@ export const infrastructureContainer = { appwrite: { client, databases, + tablesDB, storage, account, functions,