d582f15681
- Implemented tests for import polling functionality, ensuring correct behavior for active and terminal import statuses. - Created tests for the login page, validating user interactions and error handling. - Added unit tests for money utility functions, covering parsing, formatting, and summation of monetary values. - Developed tests for query keys, ensuring proper scoping and invalidation roots. chore: setup testing environment and configuration - Added setup file for testing with Vitest and Testing Library. - Configured TypeScript and Vite for the frontend project. - Created Docker and Nginx configurations for local development and production environments. - Established a PostgreSQL initialization script for setting up application roles. docs: add README and environment configuration for infra - Included README for the infra directory, detailing local development setup and service descriptions. - Created an example environment configuration file for local development with placeholders for sensitive information.
2.5 KiB
2.5 KiB
ADR 0004: Provider-neutral images and encrypted data boundary
- Status: Accepted
- Date: 2026-09-11
- Scope: deployment neutrality, data residency, object encryption, secret handling
Context
Bank statement files are sensitive personal/financial data. Legal requirements (to be confirmed by qualified counsel before real invites) demand that hosting, database, object storage and backups reside in the Russian Federation. The hosting provider may change; no cloud-proprietary service may become load-bearing. External AI calls are out of MVP scope.
Decision
- Backend and frontend ship as provider-neutral OCI images (
infra/docker/), depending only on commodity services: PostgreSQL, Redis, S3-compatible object storage, SMTP, and a secret manager — all locatable in the RF. Nothing in the images references a specific cloud API. - Statement files are envelope-encrypted before storage: a random AES-256-GCM data-encryption key (DEK) per file, with the encrypted DEK and nonce stored in PostgreSQL and the key-encryption key (KEK) held only in the secret manager. Object keys are random and carry no PII. KEK rotation rewraps DEKs.
- Deletion is crypto-shredded: space purge removes rows and objects and destroys DEKs, so restored backups cannot resurrect file contents (see
docs/operations/deletion-ledger.md). - Secrets live only in the environment/secret manager. Nothing secret is committed to Git or compiled into
VITE_*frontend variables; the frontend requires no secrets at all (same-origin/api/v1). - API/worker make no outbound AI or third-party calls in MVP; the worker additionally has no egress in production.
- Observability is provider-neutral (health/readiness, queue depth, parser duration/failure per adapter version) and never carries financial payloads.
Consequences
- The platform must supply managed PostgreSQL/Redis/S3/SMTP and a secret manager in the RF; KEK loss means permanent loss of stored statement files, so KEK backup is mandatory.
- Envelope encryption is not zero-knowledge: a compromised running API/worker plus KEK can decrypt files, so break-glass isolation and audit remain necessary.
- Provider neutrality is a hard architectural rule: reintroducing a cloud-specific dependency later would force a migration (treat as hard to reverse).
Alternatives rejected
- Single-provider managed SDKs — vendor lock-in conflicts with RF-hosting flexibility.
- Server-side (SSE) bucket encryption only — insufficient given the sensitivity of raw bank statements and the crypto-shred deletion requirement.