Aori — Roadmap Implementasi dan Blueprint Eksekusi
Status: hidup dan wajib diperbarui pada setiap perubahan domain. Peta dokumen: 01.index. Source of truth arsitektur: 03.overview. Uji alur bisnis/invariant: 04.study. Aturan kerja agent/contributor:
AGENTS.mdpada root repository.
Dokumen ini bukan daftar fitur biasa. Ini adalah urutan implementasi Aori sebagai SaaS multi-tenant dan multi-database. Sebuah item hanya boleh dicentang setelah kontrak API, authorization, entitlement bila relevan, validasi, UI, error state, invalidation, test, dan dokumentasi selesai sesuai boundary-nya.
1. Cara Membaca dan Memperbarui
| Tanda | Makna |
|---|---|
[x] | Selesai pada boundary yang disebutkan; tetap dapat membutuhkan hardening. |
[~] | Sebagian tersedia; detail setelah tanda wajib diselesaikan sebelum dianggap production-ready. |
[ ] | Belum dibuat. |
BLOCKED | Tidak aman diteruskan tanpa kontrak, policy, atau dependency yang disebutkan. |
Setiap perubahan wajib memperbarui item terkait dengan tanggal, ringkasan hasil, validasi yang dijalankan, dan kendala. Jangan mencentang berdasarkan adanya model Prisma saja. Jangan mencentang UI bila API belum tenant-scoped dan terotorisasi.
Snapshot implementasi — 2026-10-22
[x]Identity/auth dasar, User profile/personalization, Organization, Member/RBAC, Organization profile, address/link/FAQ, Workspace dasar, Team, Position, dan Employee lifecycle dasar tersedia pada Runner/API/container.[x]Billing schema/client dan katalog Plan publik tersedia; evaluator internal entitlement feature tersedia.[~]Project dapat dibuat dan status diubah; belum lifecycle/detail lengkap.[~]Collaboration API telah memiliki draft + owner party, party invite/accept, approval decision, activation, owner-workspace link, dan external participant. Container baru menyediakan draft/list/party acceptance; UI operasional detail, document lifecycle, quota metering, dan access enforcement lanjutan belum selesai.[ ]HR lanjutan (contract, shift, attendance, compensation, payroll), Catalog, Commerce, Inventory, outbox/inbox, observability/audit/retention production belum selesai.
2. Blueprint Kepemilikan dan Dependency Database
| Database | Owner/sumber kebenaran | Tenant key | Konsumen | Larangan mutlak |
|---|---|---|---|---|
| Runner | User, auth, Organization, Member/RBAC, Workspace, Team, Project, Collaboration, HR | relasi Organization | semua domain | owner product/order/stock atau join lintas DB |
| Billing | BillingAccount, Plan, Subscription, Entitlement, UsageRecord, BillingInvoice/Payment Aori | scalar organizationId tervalidasi | Runner/Catalog/Commerce/Inventory | memberi permission actor atau menggantikan Commerce invoice |
| Catalog | product/service, price list, promotion | scalar organizationId | Commerce, Inventory read model | FK Prisma ke Runner atau mutasi stock/order |
| Commerce | customer, cart, order, invoice customer, payment, shipment | scalar organizationId | Catalog/Inventory via event/projection | mempercayai harga/actor dari browser atau menjadi Billing |
| Inventory | warehouse, reservation, stock, immutable movement | scalar organizationId | Catalog/Commerce via event/projection | menerima quantity/price/tenant sebagai fakta client |
Semua komunikasi lintas domain mengikuti pola:
command di owner DB
→ local transaction + outbox event ber-idempotency
→ publisher
→ inbox consumer per domain
→ projection/read model atau compensation/reconciliationTidak ada transaction Prisma, cascade, foreign key, atau join MongoDB lintas lima database. ID lintas domain adalah reference opaque/scalar yang divalidasi oleh service pemiliknya.
3. Gate Universal Sebelum Fitur Dianggap Selesai
- Kontrak request/response/error code ditulis dan divalidasi di API secara mandiri tanpa Zod; unknown field, nested object, pagination, enum, format, dan size limit ditolak.
- Actor dari session/trusted proxy;
userId, role, ownership, tenant, price, total, status, serta permission dari client tidak pernah dipercaya. - Tenant scope dimulai dari resource owner dan diverifikasi kembali untuk relation.
- Authorization dan entitlement adalah dua pemeriksaan terpisah; quota dihitung oleh domain pemilik resource secara atomik.
- Mutation yang dapat retry memiliki idempotency key atau invariant unik yang aman; race condition diuji.
- Response hanya berisi projection aman; BigInt serialisasi aman sebagai string.
- Container mem-parse seluruh network payload melalui Zod v4 di
schema/. - UI memiliki loading, empty, forbidden, error, success, keyboard/focus, i18n, invalidation/refetch yang eksplisit; mutasi sensitif tidak optimistic.
- Test normal, unauthorized, forbidden, tenant mismatch, duplicate/retry, expiry, stale state, dan retention bila relevan telah dijalankan.
4. Tahap 0 — Engineering Governance dan Platform Baseline
Dependency: tidak ada. Database: seluruhnya. Tujuan: menjadikan perubahan berikutnya aman, terukur, dan dapat ditelusuri.
[~]Monorepo, internal packages, container host, API proxy, i18n, form primitive, HTTP status, dan Prisma clients tersedia.- Catatan: import ESM
packages/auth/src/validation.tstelah dinormalisasi untuk NodeNext; typecheck API perlu dijalankan ulang pada akhir tahap untuk memastikan tidak ada blocker toolchain lain. - Catatan: lint container terblokir resolusi lama
eslint-config-next/core-web-vitals.
- Catatan: import ESM
[~]Initial-load Container dipisahkan dari data non-kritis: server session/cookie menjadi first paint; daftar multi-session memakai snapshot session aktif dan hanya melakukan refresh authoritative lewat aksi eksplisit. Personalization kini dipisahkan daricontext-session; policy sync lintas-device sengaja belum diaktifkan kembali. Sisa: ukur Web Vitals dan audit provider/layout lain untuk waterfall atau refresh loop.[ ]Perbaiki blocker toolchain tanpa mengubah semantics aplikasi; CI menjalankan lint/typecheck/test untuk semua workspace.[ ]Establish API contract tests, integration test database terisolasi, seed aman, fixture multi-tenant, dan test idempotency.[ ]Structured log, request/correlation ID, metrics, trace, health/readiness, error taxonomy, alert policy, dan dashboard operasi.[ ]Security baseline: secret rotation, CSP, rate limit, abuse detection, dependency audit, backup/restore drill, vulnerability response, dan incident runbook.[ ]ADR (architecture decision record) untuk tenancy, eventing, document/media, payment provider, data retention, dan external collaboration.
5. Tahap 1 — Identity, Session, Profile, dan Personal Privacy
Owner: Runner. Actor: User global. Tidak membuat Organization otomatis.
[x]Signup/signin/signout, multi-session, credential navigation, password flows, User, Account, Session, Verification, UserProfile, dan personalization dasar.[x]Onboarding awal hanya profile User; user tanpa Organization tetap valid.[~]Personalization sync lintas device dan cookie snapshot diperbaiki.- Sisa: test multi-device/focus/reconnect/locale transition secara otomatis.
[ ]Passkey lifecycle: enrol, challenge, recovery, revoke, device label, audit.[ ]TwoFactor lifecycle: policy enforcement, backup/recovery code, revoke, audit.[ ]OAuth account linking/unlinking dan collision account policy.[ ]Privacy/export/delete request: legal hold, notification, delayed purge, export, and redaction projection lintas domain.[ ]JWK/key rotation dan token/session compromise response.
Exit gate: user dapat memakai aplikasi tanpa tenant; semua auth mutation aman terhadap open redirect, CSRF/session fixation, retry, enumeration, dan rate-limit abuse.
6. Tahap 2 — Organization, Membership, RBAC, dan Workspace Dasar
Owner: Runner. Tenant root: Organization. Dependency: Tahap 1.
[x]Organization/profile creation, owner Member, active organization selection, member invitation/accept/revoke, Permission/PermissionRole, RoleHistory dasar.[x]Workspace CRUD dasar; Workspace tidak dapat ada tanpa Organization.[~]Member ↔ WorkspaceMember assignment tersedia lewat management Member.- Sisa: dedicated workspace member lifecycle, suspend/revoke reasons, audit list, pagination/filter/search, dan permission granularity.
[ ]Permission catalog lifecycle: migration/versioning, role template, effective permission inspection, break-glass policy, review/certification, audit export.[ ]Organization archive/export/retention policy; child organization semantics bila dipertahankan harus tidak mengaburkan tenant root.[ ]Organization category vocabulary/template system: hanya presentation/module order, tidak pernah memberi role, feature access, entitlement, atau URL palsu.[ ]Workspace operational resource model dan per-request access middleware yang memeriksa owner organization + membership/participant state.
Study verification: 04.study.md STEP 2–6, 9, 14, 15.
7. Tahap 3 — Internal Organization Structure dan HR Foundation
Owner: Runner. Dependency: Member/RBAC. Data sensitivity: tinggi.
[x]Team (organizationIdwajib,workspaceIdopsional), TeamMember tenant-safe, Position hierarchy, Employee conversion from active Member, EmployeePositionHistory, basic lifecycle status, dan UI dasar.[~]Team lifecycle.- Archive UI telah memakai endpoint archive (bukan delete), sehingga sejarah tetap attributable. Edit Team UI dan assignment revoke telah terintegrasi di host container dengan validasi Zod v4, server action PATCH/DELETE yang tenant-safe, dan refresh otoritatif.
- Sisa: Team policy/leadership model, audit/history viewer, dan pagination untuk tim/member besar.
[~]Position lifecycle.- Update/deactivate UI telah menggunakan validasi Zod dan API hierarchy-cycle check.
- Sisa: historical assignment impact, role/grade policy, dan detail/audit viewer.
[~]Employee lifecycle.- Sisa: employee detail boundary, change position UI + history viewer, sensitive field encryption/redaction/audit, rehire, termination reason, document references, bulk import.
[ ]EmployeeContract: contract type, effective dates, renewal, expiry, signed document opaque reference, approval, archive/legal retention.[ ]Shift and EmployeeShift: timezone, schedule, recurrence, conflict detection, assignment, effective date, absence/holiday policy.[ ]EmployeeAttendance: clock-in/out, geolocation/device/privacy policy, correction, approval, anti-fraud, immutable audit, shift integration.[ ]EmployeeCompensationComponent: money minor-unit BigInt, effective date, immutable version/snapshot, approval, tax/BPJS policy, no client calculation.[ ]BankAccount: encrypted/redacted fields, verification, access audit, change approval.[ ]Payroll/PayrollItem: period lock, server calculation, attendance/contract snapshot, approval/payment lifecycle, immutable finalized ledger, correction by reversal, export, archive/purge/legal hold.
Study verification: 04.study.md STEP 5, 7–12, 14.
8. Tahap 4 — Project, Collaboration, dan External Workspace Access
Owner: Runner + Billing entitlement. Dependency: Tahap 2, Team/Member, Billing entitlement. Security rule: external person never becomes Member of host tenant.
4A. Project
[x]Project create/list/status update with tenant permission.[~]Full basic edit (name, code, description, timeline, status) is available through the same server-validated Project contract as creation.- Selesai pada tahap ini: tenant-scoped code uniqueness validation, lifecycle transition policy (draft → active/cancelled, active ↔ on_hold, terminal completion/cancellation → archived), serta compare-and-set update untuk mencegah stale status transition menimpa perubahan terbaru.
- Sisa: deliverable/timeline/budget model, Project–Workspace association, Project audit/read model.
4B. Collaboration aggregate
[x]Draft creates accepted owner party atomically.[x]Party invitation with organization/team/representative, scope subset, validity boundary, accepted party flow, approval requirement/decision, activation gate, owner-workspace link, and external WorkspaceParticipant API.[x]collaboration.enabledfeature entitlement is checked for owner-side mutations.[~]Container supports draft/list, acceptance by invited tenant, serta owner-side proposal dan reversible suspend/resume dengan authoritative refresh. Owner dapat menambah approval requirement untuk party yang sudah ada serta meminta aktivasi; API tetap memutuskan kelayakannya.- Sisa: permission-aware owner console for party invite, approval decision, workspace link, participant assignment/revoke, status/history detail, dan confirmation+reason UX untuk termination/archive.
[ ]CollaborationDocument: document/media service contract, opaque document reference, issuer validation, verification metadata, NDA/agreement/minutes/attachment, expiry, access policy, immutable audit, retention/legal hold.[~]Lifecycle transitions owner-side: propose, suspend/resume, terminate, archive, revoke non-owner party (termasuk revoke seluruh external participant terkait), dan revoke external participant sudah tersedia pada API.- Sisa: automatic expiry job, party suspension/resume, reason/note/audit event per mutation, notification, UI lifecycle operasional, dan policy archive/retention.
[ ]requiredByTeamRolerequires an explicit Team role model/policy before it is exposed; do not pretend TeamMember has a role it does not store.[ ]Entitlement quotas: external party max, workspace max, external participant max; owner domain atomically counts usage then emits idempotent UsageRecord to Billing.[ ]Access middleware on every workspace resource checks Collaboration active, party accepted, approval complete, scope subset, participant active, validity windows, and immediate revocation/expiry.[ ]Cross-organization organization discovery/invitation policy. Do not expose a global tenant directory without privacy, anti-enumeration, and consent design.
Study verification: 04.study.md STEP 17–18; especially 17 Agustus multi-party scenario.
9. Tahap 5 — Billing, Subscription, Entitlement, dan Retention
Owner: Billing. Dependency: Runner organization exists. Boundary: Billing grants capability/quota, never actor permission.
[x]Billing schema/client, Plan version model, public active-plan catalogue, and internal effective feature entitlement lookup.[~]Container pricing board reads public plan data.- Sisa: UI must never hardcode source-of-truth price/features.
[ ]BillingAccount creation and tenant ownership verification against Runner.[ ]Subscription checkout command: provider abstraction, idempotency key, secure redirect, provider reference secrecy, webhook signature/replay validation.[ ]Subscription state machine: trial/active/grace/restricted/ended/archived; billing projection to effective Entitlement with deterministic precedence.[ ]Entitlement evaluator including quota values and atomic usage decision contract.[ ]UsageRecord inbox/outbox/metering: producer idempotency key, dedupe, retry, reconciliation, late event policy; no synchronous Billing write in operational request.[ ]BillingInvoice/BillingPayment lifecycle; explicitly distinct from Commerce invoice/payment.[ ]Restricted read-only enforcement, account archive, retention/legal hold, notification, export window, purge job and irreversible deletion safeguards.
Study verification: 04.study.md STEP 16 and retention section.
10. Tahap 6 — Catalog Domain
Owner: Catalog. Dependency: Organization scalar tenant key + Billing entitlement + Runner authorization composition. No Runner FK.
[~]Product/category functionality operates against Catalog database through tenant/RBAC composition. Product create/update/archive now appends an idempotent Catalog outbox event in the same local transaction; archive replaces physical delete. Price lists and immutable price versions now have tenant-scoped API contracts; price mutations reject floating-point money and overlapping active target/tier validity windows, then appendcatalog.price.changedlocally.- Price entry host sekarang dimulai dari Product → valid PriceList → immutable Price version; list validity diperiksa lagi API sebelum write dan history dibatasi ke Product terkait. Perintah create Price kini membawa UUID idempotency key yang tersimpan bersama hash payload privat. Retry dengan payload sama mengembalikan versi yang telah dibuat; reuse key untuk payload atau PriceList lain ditolak tanpa membuat versi baru.
- Sisa: outbox publisher lease/retry/dead-letter, Inventory/Commerce inbox consumers dan projections, date/tier price editor lengkap, dan migration of remaining legacy product naming.
[ ]Catalog schema finalization: product/service, category, variant, attribute, media opaque references, price list, tax class, promotion eligibility, status/version.- ProductVariant API lifecycle is available (tenant resolution through parent Product, manual bounded attributes validation, archive-not-delete, and parent projection event). Host juga telah memiliki action archive tenant-scoped dengan refresh otoritatif. Media, identifiers, categories, service definitions, tax, promotion, and read-model contracts are still not exposed.
[ ]Catalog APIs: tenant scope, product permission, entitlement, pagination/filter/search, immutable price versioning and BigInt money.- Category legacy handlers now reject unknown/invalid input, resolve parent categories in the same tenant, hide archived rows, and archive instead of physically deleting. Search, pagination, entitlement, media and complete category/product composition remain open.
[ ]Event contracts:catalog.product.published,catalog.price.changed,catalog.product.archived; idempotent consumers and projection versioning.- Versi awal
@repo/eventssekarang mendefinisikan envelope JSON-safe berversi dan payload Catalog Product/Price. Outbox Catalog menyimpan envelope tersebut denganeventIdyang sama; correlation/causation masihnullsampai request context dan publisher/inbox lintas domain tersedia.
- Versi awal
[ ]Container/catalog MFE routes with safe Zod schemas, server access gating, list/detail, form, error/empty/loading and cache invalidation.- Container sekarang memiliki host route
/org/[slug]/cataloguntuk Product identity/content: server access gate, Zod v4 response/form validation, create/edit pessimistic refresh, loading transition, empty/error access state, dan shortcut capability kategori yang hanya muncul setelah route benar-benar ada. Variant nested route tersedia untuk identity SKU turunan Product yang tervalidasi dan dapat diarsipkan. PriceList metadata juga dapat dibuat/dibaca/diarsipkan dari host; entry harga per produk memakai idempotency key, sedangkan pagination, granular navigation permission/entitlement, date/tier editor, dan MFE remote boundary masih terbuka.
- Container sekarang memiliki host route
11. Tahap 7 — Inventory Domain
Owner: Inventory. Dependency: Catalog projection; entitlement; warehouse permission. Rule: stock truth is immutable movement ledger, not client quantity.
[ ]Warehouse, location/bin, stock item/balance projection, reservation, lot/batch, serial policy, stock movement/adjustment/transfer/count schemas.[ ]Reservation lifecycle with idempotency and expiry; authoritative availability endpoint.[ ]Inventory commands validate tenant, authorization, product projection, quantity bounds, concurrency/optimistic version or ledger invariant; no price from client.[ ]Event contracts to/from Commerce: reserve/confirm/release/fulfill/return; compensation and reconciliation dashboard.[ ]Warehouse/inventory MFE with ledger-first UI, scan accessibility, offline policy only if reconciliation is designed; no localStorage stock source of truth.
Study verification: 04.study.md STEP 13A–13B.
12. Tahap 8 — Commerce Domain
Owner: Commerce. Dependency: Catalog projection, Inventory reservation, Billing entitlement, Runner actor composition. Commerce invoice ≠ BillingInvoice.
[ ]Customer/contact/address snapshot model; customer identity/privacy policy.[ ]Cart/quote/order state machine, server-authoritative price/tax/discount snapshot, idempotent checkout/order command, cancellation/return/refund policy.[ ]Customer Invoice, Commerce payment, shipment/fulfilment lifecycle; provider webhooks validated, replay safe, monetary amounts BigInt minor units.[ ]Outbox/inbox flows with Inventory and Catalog projections; reserve → confirm/release, shipment events, failed compensation and reconciliation.[ ]Commerce MFE routes with permission/entitlement gate, authoritative mutation result, no optimistic stock/payment/order finality.
13. Tahap 9 — Cross-Domain Read Models, Eventing, and Reconciliation
Dependency: each owner domain command is stable first.
[ ]Shared event envelope: event ID, aggregate/version, organizationId, occurredAt, correlation/causation ID, schema version, idempotency key, PII classification.[ ]Per-database outbox, publisher lease/retry/dead-letter and inbox dedupe tables.[ ]Consumer ordering/duplicate/out-of-order strategy; poison-event tooling and replay.[ ]Projection/composition service contracts for dashboard/search/report; no hidden cross-DB join from UI request.[ ]Reconciliation jobs for subscription usage, catalog/commerce price mismatch, commerce/inventory reservation, payroll/payment and document references.[ ]Data migration/versioning and backfill protocol with rollback/repair plan.
14. Tahap 10 — Audit, Compliance, Data Lifecycle, and Operations
[ ]Immutable audit event model/service for access, RBAC, HR, collaboration, money, document, retention, and privileged support action.[ ]Actor impersonation/support policy with explicit consent, audit, expiry and no secret exposure.[ ]Data classification, PII redaction, encryption-at-rest/field encryption, key access, download watermarking where required.[ ]Retention policy engine: active → archived → legal-hold check → warning/export → scheduled purge; every job idempotent and auditable.[ ]Organization backup/export, restore boundaries, disaster recovery RPO/RTO test.[ ]Operational dashboards for auth abuse, queue lag, event failures, entitlement denial, collaboration expiry, payroll lock, stock reconciliation, and data purge.
15. Tahap 11 — Product Experience, MFE, and Scale
[~]Mobile auth foundation berada pada repository saudaraC:\Data\AORI-Projects\aori-mobile: Expo Router protected groups memisahkan route publik dan operasional; credential email/password memperoleh bearer session Better Auth melalui API, token hanya disimpan di Expo SecureStore, dan cold start selalu memvalidasinya kembali lewatget-session.- OAuth provider (Google, GitHub, Apple, Microsoft bila dikonfigurasi) kini memakai mobile grant bridge: API membuat attempt berumur 10 menit dengan exchange-secret yang hanya ada di memori aplikasi, Better Auth menyelesaikan provider di browser, dan callback deep-link membawa grant opaque sekali pakai—bukan session/bearer token. API mengenkripsi token cookie sementara menggunakan
BETTER_AUTH_SECRET, menukarnya sekali melalui HTTPS, lalu menghapus verification record secara atomik.AORI_MOBILE_AUTH_CALLBACK_URLpada API danEXPO_PUBLIC_AORI_AUTH_CALLBACK_URLpada mobile harus identik (aori://auth/callback); nilai default hanya untuk local development. - Batas saat ini: MFA, passkey, recovery, account linking/unlinking, device/session management, API client domain, Zod response schema mobile, i18n, dan universal-link/app-link hardening belum tersedia.
EXPO_PUBLIC_AORI_API_URLharus diarahkan ke HTTPS/reachable API (bukanlocalhostpada perangkat fisik). Bridge tidak boleh dianggap pengganti universal link pada production. - Lokasi implementasi aktif:
C:/Data/AORI-Projects/aori-mobile. SDK 58 memerlukan root route konkret disrc/app/index.tsx; route tersebut dilindungi bersama(app), sementaraStack.Protectedmenjadi satu-satunya mekanisme redirect menuju auth agar perubahan sesi tidak menciptakan loop navigasi. Respons user Better Auth diparse menjadi projection aman sebelum dipakai state sesi. [~]Mobile profile edit memakaiPATCH /api/users/medengan bearer session, validasi input lokal minimal, state submitting yang menonaktifkan field, dan update state hanya dari respons API tervalidasi. Avatar/media, verifikasi telepon/email, recovery, dan pengelolaan session/device tetap belum tersedia.[~]Mobile security screen tidak lagi memakai switch dua faktor atau daftar perangkat palsu. Ia hanya menampilkan status two-factor dari projection sesi; password, re-authentication, recovery, dan session/device management menunggu lifecycle native yang lengkap.[~]Mobile notification screen tidak lagi menyimpan toggle lokal semu. Delivery preference menunggu push-token registration, izin perangkat, preference API, dan audit delivery yang konsisten.[~]Mobile password change tersedia melaluiPOST /api/users/me/password: current password, password baru, dan pilihan revoke sesi lain dikirim melalui bearer session; API tetap memeriksa freshness/policy/password lama dan UI tidak melakukan optimistic update. Device-session inventory dan MFA management tetap belum tersedia.[~]Mobile Organization context dapat membaca profil tenant yang member-safe melaluiGET /api/organization/:organizationId, hanya atas aksi eksplisit, dengan parse runtime dan race protection. Endpoint Workspace masih owner-only sehingga tidak dipakai sebagai daftar Workspace universal untuk Member.[~]GET /api/users/me/readinessmenyediakanUserProfileReadinessv1 yang identity-only; Dashboard mobile merender progress profil dari respons tervalidasi, lazy pada focus dengan throttle dan stale-response guard.OrganizationReadinessdanMemberWorkReadinessbelum dibuat karena membutuhkan checklist permission/entitlement dan lifecycle membership yang tidak boleh disatukan.
- OAuth provider (Google, GitHub, Apple, Microsoft bila dikonfigurasi) kini memakai mobile grant bridge: API membuat attempt berumur 10 menit dengan exchange-secret yang hanya ada di memori aplikasi, Better Auth menyelesaikan provider di browser, dan callback deep-link membawa grant opaque sekali pakai—bukan session/bearer token. API mengenkripsi token cookie sementara menggunakan
[~]Mobile Organization context memuat projection aman dariGET /api/users/me/organizationshanya atas aksi eksplisit pengguna, mem-parse respons network sebelum dipakai, dan memilih konteks hanya di memori. Provider di-remount peruser.idagar tenant akun sebelumnya tidak pernah tampak setelah sign-out/sign-in. Route/tab yang sebelumnya bernama Workspace telah dimigrasikan menjadi Organization karena layar ini bukan daftar Workspace.- Layar Organization mobile kini melakukan initial load saat route mendapat focus, hanya ketika state masih
idle; refresh manual tetap tersedia dan selection tetap memory-only. Request tidak dipicu dari render dan tidak mengubah boundary authorization API. [~]Dashboard, aktivitas, Catalog, dan Commerce mobile tidak lagi mengonsumsi data contoh perangkat. Saat kontrak read model tenant-scoped belum ada, layar menampilkan empty/unavailable state yang jelas. Daftar Workspace juga sengaja belum diintegrasikan: endpoint yang ada saat ini owner-only, sehingga tidak aman dipakai sebagai daftar universal bagi Member.[~]Ikon navigasi dan affordance mobile memakaiexpo-symbolsatau image asset yang valid; ikon berbasis karakter string dan data mock legacysrc/data/workspace.tstelah dihapus. Penggantian icon native tab dapat tetap memakai asset raster multi-ukuran yang sudah tersedia.
- Layar Organization mobile kini melakukan initial load saat route mendapat focus, hanya ketika state masih
[ ]Route map per capability/MFE with host ownership, remote boundary, contract version, fallback/error isolation, and progressive loading.[ ]Mobile Remote Config/SDUI/OTA foundation: policy telah dikunci pada root dan mobileAGENTS.md(presentational-only config, validated native registry/action allowlist, built-in fallback, tenant-safe delivery, dan OTA runtime boundary). Implementasi service/config API, cache, registry, Dashboard pilot, test matrix, dan EAS Update activation belum dimulai.[ ]Navigation derived from permission + entitlement + capability availability; category changes labels/template only.[ ]Responsive/mobile, keyboard, screen-reader, locale/RTL, timezone/currency formatting, large-list virtualisation/pagination, and performance budgets.[ ]Notification center, email/push preference, digest, delivery audit, and external invite notification with privacy-safe content.[ ]Search/read model, reporting/export, analytics consent, usage reporting, and data minimization.[ ]Multi-region/scale plan: tenant routing, cache key tenancy, rate limits, queue partitioning, backpressure, SLOs, capacity/load/chaos tests.
16. Route and Contract Delivery Checklist
Untuk setiap route baru, tambahkan baris status di fase domain terkait dan pastikan:
- Owner DB, tenant scalar/relation, actor, permission, entitlement, lifecycle, and data classification dicatat.
- API validates parameter/query/body manually; unknown keys rejected; response projection safe; idempotency stated.
- Event/outbox/projection impact dicatat bila menyentuh database lain.
- Container Zod schema, server gate, mutation invalidation, i18n, accessibility, and states selesai.
- Test matrix dan
04.study.mdscenario mapping diperbarui. - Checklist dalam roadmap diperbarui bersama catatan positif/kendala/risiko.
17. Change Log Roadmap
| Tanggal | Perubahan | Keterangan |
|---|---|---|
| 2026-10-22 | Roadmap dibuat | Baseline menyatukan status Runner/Collaboration dan semua domain lima database. |
| 2026-10-22 | Collaboration foundation | API lifecycle awal tersedia; UI detail, document, quota metering, access enforcement, dan eventing masih terbuka. |
| 2026-10-22 | Collaboration revocation lifecycle | API menambahkan propose/suspend/resume/terminate/archive serta revoke party/participant; UI, expiry job, audit event, dan notification belum tersedia. |
| 2026-10-22 | Collaboration owner UI lifecycle | Container menambahkan proposal dan suspend/resume yang reversible; action terminal ditahan sampai confirmation/reason/audit UX tersedia. Container typecheck lulus. |
| 2026-10-22 | Project basic edit | Container menyatukan edit detail dan status Project pada kontrak API tervalidasi; budget/deliverable/workspace/audit belum dimodelkan. |
| 2026-10-22 | Collaboration approval/activation UI | Owner dapat membuat requirement approval pada party yang sudah ada dan meminta aktivasi; projection party memakai display name aman. Container typecheck lulus. |
| 2026-10-22 | Catalog outbox foundation | Product create/update/archive menulis event lokal idempoten dalam transaksi Catalog; hard delete diganti archive. Publisher dan consumer Inventory/Commerce belum dibuat. |
| 2026-10-22 | Catalog pricing foundation | PriceList dan Price version memiliki route tenant/RBAC, validasi minor-unit BigInt, validity/tier overlap check, serialisasi HTTP aman, serta outbox catalog.price.changed; belum ada publisher/consumer maupun UI. |
| 2026-10-22 | Catalog host pricing plug | Container memiliki descriptor proxy, schema Zod v4, dan server service untuk price-list/history; route UI tetap belum diekspos sampai manajemen Catalog dan i18n siap. |
| 2026-10-22 | Catalog variant lifecycle | Variant product dapat dibaca/dibuat/diubah/diarsipkan dalam tenant parent Product, atribut dibatasi, dan perubahan memicu projection event Product; typecheck API hanya masih terblokir import ESM legacy di packages/auth. |
| 2026-10-22 | Catalog category boundary | Handler kategori legacy diperketat dengan validasi manual, tenant-scoped parent, dan archive lifecycle; belum ada event/projection kategori maupun UI. |
| 2026-10-22 | Shared Catalog event envelope | Package internal @repo/events ditambahkan; outbox Catalog memakai envelope schema v1 JSON-safe dengan event ID yang konsisten. Publisher, inbox, correlation context, dan transport masih BLOCKED oleh ketiadaan worker/broker. |
| 2026-10-23 | Catalog Product host surface | Container menambahkan route Product tenant-scoped dengan Zod, server gate, form reusable, refresh authoritative, serta i18n; Product belum mencakup price, stock, variant, media, atau pagination. |
| 2026-10-23 | Catalog Variant host surface | Container menambahkan route nested Variant yang mengambil parent Product detail (bukan daftar berpagination), memakai Zod, dan melakukan refresh otoritatif setelah mutation. Stock dan harga tetap tidak dimodelkan pada Variant. |
| 2026-10-23 | Catalog PriceList host surface | Container menambahkan route PriceList tenant-scoped dengan create/list Zod dan refresh otoritatif. Entry harga per Product ditahan sampai pemilih Product yang aman dan terpagination tersedia. Container TypeScript lulus. |
| 2026-10-23 | Catalog Product price flow | Harga kini dibuat dari Product menuju PriceList valid lalu Price version minor-unit; API memfilter history menurut Product dan menolak list yang berada di luar masa berlaku. Publisher/inbox dan idempotency command masih terbuka. |
| 2026-10-23 | Catalog Product archive host action | Product archive memakai endpoint tenant/RBAC yang sudah ada dan refresh otoritatif; riwayat referensi tidak dihapus. PriceList dan Variant archive UI masih terbuka. |
| 2026-10-24 | Catalog price idempotency & Variant archive | Price menyimpan idempotency key dan hash payload privat untuk replay aman/race retry; reuse key lintas payload ditolak. Host dapat mengarsipkan Variant melalui parent Product tenant scope dan refresh otoritatif. Prisma Catalog serta shared DB types telah digenerate; API typecheck masih terblokir empat import ESM legacy packages/auth/src/validation.ts. |
| 2026-10-24 | Catalog PriceList archive | PriceList sekarang diarsipkan (bukan dihapus) melalui permission price.manage, menonaktifkan list/default flag, dan mempertahankan Price immutable untuk audit/history. Host memakai action tenant-scoped dengan refresh otoritatif. |
| 2026-10-24 | Container bootstrap performance | Session server/cookie dipakai untuk first paint; fetch multi-session dipindahkan ke dialog/halaman khusus. Revalidasi personalization dibuat background, tervalidasi Zod, dedupe/throttle focus, dan tidak lagi melakukan refresh route pada sync normal. Container TypeScript lulus; pengukuran Web Vitals serta audit provider lain masih terbuka. |
| 2026-10-24 | Session/personalization isolation & auth navigation | Personalization dipindahkan dari context-session ke hook snapshot tanpa effect/fetch bootstrap; sinkronisasi lintas-device ditunda sampai policy baru siap. Dialog/halaman multi-session tidak lagi auto-refresh; user memilih refresh authoritative. Auth browser dipaksa melalui proxy same-origin dan sign-up menerima callback URL agar cookie dan navigasi berada pada boundary yang sama. Container TypeScript lulus; profiling browser autentikasi masih diperlukan. |
| 2026-10-24 | Mobile credential auth foundation | aori-mobile memakai Expo Router protected route serta Expo SecureStore. Better Auth bearer token diambil dari header set-auth-token, disimpan encrypted, dan divalidasi ulang terhadap API saat cold start; token tidak menggunakan AsyncStorage/cookie/URL. TypeScript mobile lulus. OAuth, MFA, dan native recovery tetap terbuka. |
| 2026-10-25 | Mobile workspace SDK 58 migration | Implementasi aktif kembali berada di aori-mobile. Root starter diganti dengan route pengarah sesi src/app/index.tsx; plugin Expo untuk SecureStore, font, image, status bar, dan web browser dinyatakan kembali di app config. |
| 2026-10-25 | Mobile protected-route sign-out fix | Root index kini berada di group guard autentikasi yang sama dengan (app) dan hanya mengarah ke operasi saat guard lolos. Stack.Protected dengan redirectTo="/sign-in" menjadi satu-satunya redirect logout; ini menghilangkan redirect bersaing yang memicu maximum update depth. |
| 2026-10-25 | Mobile auth response boundary | Respons sign-in, sign-up, dan get-session tidak lagi di-cast secara buta. Mobile hanya menerima projection AuthUser dengan scalar yang tervalidasi; ISO date tetap string pada boundary JSON. Respons tidak valid memicu validasi sesi ulang atau penolakan sesi. |
| 2026-10-25 | Mobile profile edit | Profile mobile dapat mengubah nama, username, dan nomor telepon melalui PATCH /api/users/me yang sudah ada. Mutation bearer-scoped, input form dibatasi sebelum request, dan state user diganti hanya memakai projection respons yang tervalidasi. |
| 2026-10-26 | Collaboration party invite contract | Container menambahkan schema Zod v4 dan server service untuk owner-side party invitation pada endpoint API yang sudah tersedia. UI invite, organization discovery, team/representative selectors, audit reason, dan pagination masih terbuka; tidak ada endpoint baru atau mock tenant dibuat. |
| 2026-10-26 | Collaboration discovery privacy boundary | API menambahkan discovery exact-slug yang hanya mengembalikan projection publik terbatas setelah collaboration.manage; free-text/global enumeration ditolak, owner tenant tidak dapat ditemukan melalui endpoint ini. UI selector lengkap masih perlu diselesaikan dengan i18n dan team/representative contracts. |
| 2026-10-25 | Mobile security truthfulness | Toggle two-factor lokal dan detail perangkat mock dihapus. Layar keamanan kini read-only, menggunakan status twoFactorEnabled dari sesi dan menyatakan capability yang belum mempunyai lifecycle native secara eksplisit. |
| 2026-10-25 | Mobile notification truthfulness | Toggle notifikasi lokal dihapus. Layar notifikasi menyatakan dependency push permission/token, preference API, dan delivery audit sebelum preference dapat dimutasi dari mobile. |
| 2026-10-25 | Mobile credential and Organization expansion | Mobile membuka perubahan password melalui kontrak User yang telah ada (server tetap memverifikasi session/password/policy) dan menambahkan pembacaan profil Organization yang member-safe atas aksi eksplisit. Daftar sesi, MFA, dan Workspace member-safe masih belum tersedia. |
| 2026-10-25 | User profile readiness v1 | API menambahkan projection readiness identity-only pada User; Dashboard mobile menampilkan progress nyata tanpa menyebut Workspace atau mewajibkan Organization. Checklist tenant dan kerja anggota ditahan sebagai projection terpisah agar skenario collaboration lintas Organization tidak bocor atau salah dihitung. |
| 2026-10-25 | Mobile dynamic-delivery boundary | Instruksi root dan mobile mengunci pemisahan Remote Config, SDUI, dan OTA agar tidak dapat mengubah tenant/authorization/entitlement atau menjalankan capability arbitrer. Ini hanya policy/design guard; endpoint config, registry, cache, dan EAS Update belum diimplementasikan. |
| 2026-10-25 | Mobile tenant-context hardening | Mobile menambahkan Organization context dari endpoint user-scoped, selection memory-only, dan remount per user untuk mencegah sisa tenant lintas sesi. Route seleksi yang semula ambigu bernama Workspace diganti menjadi Organization; Workspace tetap belum ditampilkan karena route API saat ini owner-only. |
| 2026-10-25 | Mobile mock removal and icon migration | Data dashboard/activity/catalog/commerce contoh serta ikon karakter string dihapus. Semua layar tersebut kini tenant-aware dan jujur terhadap kontrak yang belum tersedia; affordance menggunakan expo-symbols/asset ikon valid. |
| 2026-10-26 | Mobile OAuth one-use grant bridge | API menambahkan start/callback/exchange native OAuth yang mengikat attempt pada exchange-secret memori, mengenkripsi token sesi sementara, dan menghapus grant atomik sesudah exchange. Mobile menampilkan provider yang benar-benar dikonfigurasi serta menyimpan bearer hanya setelah respons HTTPS. Masih perlu universal link/app link, automated expiry cleanup, rate-limit spesifik auth, dan test integrasi provider/callback sebelum production. |
| 2026-10-26 | TypeScript auth boundary | Typecheck mobile lulus setelah projection readiness mempersempit data unknown secara runtime. Import ESM pada @repo/auth/validation dinormalisasi untuk resolver NodeNext; typecheck API dijalankan ulang setelah perubahan. |
| 2026-10-26 | Mobile Organization initial load | Layar Organization memuat daftar tenant saat pertama kali mendapat focus bila belum pernah dimuat; refresh manual dan projection API tetap dipertahankan, tanpa persistence atau asumsi akses client. |
| 2026-10-26 | Auth provider platform capability | GET /api/auth/providers kini mengembalikan capability web, ios, dan android; Google memakai client ID platform masing-masing dengan GOOGLE_CLIENT_SECRET bersama. Web dan mobile memilih projection platformnya sendiri sebelum merender provider. |
| 2026-10-26 | Mobile OAuth authorization boundary | Mobile OAuth menolak authorization URL yang mengarah ke API/web Aori atau host yang tidak sesuai provider; flow tetap memakai Expo native browser auth session dan callback opaque aori://auth/callback, tanpa menaruh bearer token pada deep link. |
| 2026-10-26 | Mobile native provider sign-in | Mobile Google memakai react-native-nitro-google-signin dan Apple memakai expo-apple-authentication; API menerima credential ID token melalui endpoint mobile khusus dan meneruskannya ke Better Auth untuk validasi server-side. Native modules memerlukan development/production native rebuild, bukan Expo Go. |
| 2026-10-27 | Mobile user settings modularization | Account mobile kini memiliki module src/components/settings/user dengan menu, preferences, dan address. Address memakai endpoint user-scoped nyata dengan runtime parsing, loading/empty/error state, create, dan delete; profile, password, security, notification, provider connection, delete account, dan MFA tetap dibatasi oleh lifecycle kontrak yang tersedia. |
| 2026-10-28 | Mobile owner-agnostic address form | Mobile menambahkan components/ui/address-form.tsx yang hanya menangani input address dan menerima onSubmit dari caller. Cascading province/city/district/village serta postal-code lookup mengambil data dari endpoint geography publik dan memvalidasi response runtime; user address memakai adapter callback, sementara organization adapter belum diaktifkan di layar mobile. TypeScript mobile lulus. |
| 2026-10-28 | Mobile Select bottom-sheet gesture/scroll correction | Select mobile membatasi tinggi sheet secara eksplisit 65% viewport, memberi ruang bounded pada ScrollView agar opsi banyak dapat discroll, serta memasang root gesture handler di dalam native Modal; gesture tarik tetap dibatasi pada header sehingga tidak merebut scroll options. Runtime verification pada native development build masih diperlukan. |
| 2026-10-28 | Mobile Select sheet sizing and overlay polish | Sheet kembali intrinsik mengikuti content dengan batas maksimum 65% viewport; daftar panjang tetap memiliki batas scroll tersendiri. Spring rebound memakai overshoot clamping untuk menghilangkan gap saat kembali ke posisi awal, dan modal confirmation/select memberi tint status bar yang lebih terang agar konsisten dengan overlay. |
| 2026-10-28 | Mobile modal StatusBar compatibility | StatusBar modal disederhanakan ke barStyle karena tipe Expo/RN proyek tidak menyediakan translucent atau backgroundColor; modal memakai statusBarTranslucent dan backdrop transparan untuk mempertahankan tint overlay tanpa error TypeScript. |
| 2026-10-22 | HR structure lifecycle | Position update/deactivation dan Team archive UI ditambahkan; Team edit serta assignment lifecycle masih terbuka. |
| 2026-10-23 | Team edit & member revoke lifecycle | Container menambahkan form edit Team (nama, deskripsi, workspace reassignment) serta aksi revoke penugasan member dengan status aman dan refresh otoritatif. |
| 2026-10-28 | Sheets modal performance/accessibility | Core Sheets mengurangi listener Escape saat tertutup, memindahkan multiple-open render scheduling ke provider tunggal, mencegah setiap panel mengunci scrollbar, dan menambahkan focus trap pada modal content. Scrollbar lock kini ref-counted agar beberapa modal tidak saling menghapus style body; browser verification dan a11y test otomatis masih terbuka. |
18. Definition of Done Produk Besar
Aori tidak dianggap selesai hanya karena halaman atau model sudah ada. Target akhir tercapai apabila setiap domain owner dapat bekerja independen dengan kontrak event/versioning yang teruji; tenant tidak dapat bocor; entitlement dan permission tidak saling menggantikan; money/stock/payroll/legal record authoritative serta auditable; recovery/retention/operation teruji; dan pengalaman User, Member, Employee, owner, serta collaborator eksternal jelas tanpa memalsukan relasi Organization–Workspace–Project–Collaboration.