Files
sxchnge/README.md
T

261 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# SXCHNGE
Product repository for the sxchnge public website, Flutter consumer app, reusable
packages, and a backend for frontend (BFF) bootstrapped from Sendico.
## Current state
The consumer app includes responsive login/signup, English and Russian
localization, email verification and recovery screens, and URL-based navigation
with `go_router`. Its interface uses the shared theme's colors and typography.
**Authentication, email verification and analytics use dummy services.** No real
account or session is created, no email is delivered, and no analytics data is
transmitted by those app services. The backend now contains locally owned copies
of Sendico’s BFF runtime, auth/session stack and account service. The app is not
connected to that backend or to Sendico yet.
## Repository structure
| Location | Purpose |
| --- | --- |
| [`website/`](website/README.md) | Astro public website, assets, brand references and hosting configuration |
| [`frontend/app/`](frontend/app/README.md) | Flutter consumer app with a web runner |
| [`sxchnge_theme`](frontend/packages/sxchnge_theme/README.md) | Reusable light/dark themes and bundled Onest font |
| [`sxchnge_auth`](frontend/packages/sxchnge_auth/README.md) | Shared auth contracts, providers, two-factor page and dummy services |
| [`sxchnge_analytics`](frontend/packages/sxchnge_analytics/README.md) | Typed journey events, recorder and bounded in-memory dummy analytics |
| [`backend/`](backend/README.md) | Copied BFF/auth/account foundation and isolated public Sendico contracts |
| [`.agents/skills/`](.agents/skills) | Repository agent skills |
| [`docs/`](docs/implementation.md) | Implementation records and UX measurement contracts |
Each application owns its dependencies and build configuration. Shared Dart and
Flutter packages can be reused by a future mobile app; mobile runners are not
currently included. Local `.vscode/` configuration is ignored.
## Local Docker development
```sh
make build && make up
```
This builds the product images and starts an isolated Vault, authenticated MongoDB
replica set and NATS JetStream. First startup intentionally stops after bootstrap
until you set the Resend API key and verified sender in Vault's `kv/email` secret.
Then rerun `make up` to start notifications, BFF and the frontend at
[https://localhost:5126](https://localhost:5126).
All image inputs resolve to current stable releases and are pinned by digest for
the build. Services fetch secrets from Vault; Mongo application credentials come
from Vault's database plugin. See the [local development guide](docs/local-development.md)
for Vault provisioning, local HTTPS trust, lifecycle commands and verification.
## Run the consumer app
Requires Flutter **3.47.0 or later** with Dart **3.13.0 or later** (below Dart 4), matching
the application's package constraints, and Chrome for this run command.
```sh
cd frontend/app
flutter pub get
flutter gen-l10n
flutter run -d chrome
```
Build the web app from the same directory:
```sh
flutter build web --no-wasm-dry-run
```
Output is `frontend/app/build/web/`. To inspect that build locally, from the
repository root:
```sh
python3 -m http.server 5123 --bind 127.0.0.1 --directory frontend/app/build/web
```
Open [the local app](http://127.0.0.1:5123/). The language selector supports EN/RU
and saves the language preference. Edit translations in `frontend/app/lib/l10n/`
and regenerate with `flutter gen-l10n`; do not edit generated translations.
## Preview email verification
Signup leads to the simulated email-sent screen. Its demo confirmation button
previews completion. Direct confirmation URLs use hash routing:
| URL suffix | Preview outcome |
| --- | --- |
| `/#/verification-sent` | Request an email; a direct visit asks for the address |
| `/#/verify-email?token=demo-valid` | Simulated verification complete |
| `/#/verify-email?token=demo-expired` | Expired link with recovery |
| `/#/verify-email?token=demo-internal` | Internal error with primary retry |
| `/#/verify-email` or an unknown token | Invalid confirmation |
Signup email stays transient and is excluded from serialized browser history.
The sent recipient is read-only until **Change email** is selected. All current
routes are public; these previews do not establish authentication or authorization.
## Analytics and PostHog preparation
The app accepts an injectable `AnalyticsService` and defaults to
`DummyAnalyticsService`. It keeps up to 500 semantic events in memory and never
captures form contents, confirmation tokens or raw errors. Events cover submitted
auth journeys, service outcomes, retries and known abandonment; simulated outcomes
are distinguished from real conversion.
A future PostHog adapter can replace the sink. No PostHog SDK or credentials are
configured. Read the [auth journey contract](docs/ux/auth-journeys.md) for event
properties, attempt and timing rules, metric definitions, privacy requirements,
and cross-device/termination measurement limitations.
## Run the public website
Requires Node.js **22.12.0 or later** and npm, matching `website/package.json`.
From the repository root:
```sh
cd website
npm ci
npm run dev -- --background --host 127.0.0.1
```
Manage the background server from `website/`:
```sh
npm exec astro dev status
npm exec astro dev logs
npm exec astro dev stop
```
Website builds go to `website/dist/`. Use `website/` as the working directory
for hosting tools; the existing hosting identity lives in
`website/.openai/hosting.json`. The website and consumer app are separate builds.
## Validate changes
From the repository root, run all shared-package and app tests:
```sh
make test-frontend
```
From each changed Flutter package, run formatting and analysis. For example:
```sh
cd frontend/app
dart format --output=none --set-exit-if-changed lib test
flutter analyze
```
Validate the website independently:
```sh
cd website
npm run test
npm run check
npm run build
```
Rendering and passing tests do not alone establish UX completion. Review
usability, accessibility and journey measurement under the repository's UX rules.
## Product boundaries
The integration is: **consumer app → sxchnge BFF → Sendico public HTTP API**.
SXCHNGE is one organization in Sendico; its customers are owned locally.
Local accounts have no organization tenancy, membership, roles or policy engine.
- sxchnge will own consumer registration/sessions, onboarding and exchange UX,
and mappings from local customers to organization-scoped platform resources.
- Sendico remains authoritative for payment execution, KYC records and
verification, policy decisions and limit enforcement.
- The sxchnge organization, backend integration principal and individual customer
references are distinct identities. Consumers must not share the integration
account's customer identity.
- The BFF uses only the public HTTP API. Existing BFF/auth/account components
are copied into SXCHNGE-owned code; private transports and sibling module
dependencies are not used.
Integration credentials belong in the backend.
Before backend integration, agree on the customer, KYC, eligibility/limits and
customer-scoped payment contracts for one complete transaction flow. These are
intended boundaries, not claims that the required operations already exist.
## Client architecture
Keep **DTO → mapper → service → data model → provider → UI** boundaries in every
feature and shared package. Services return mapped domain models; providers sit
on services and expose loading/error/data state. Widgets render models and call
provider actions. DTO serialization and backend calls belong below this boundary.
Shared packages own reusable domain logic for web and mobile; stub replacements
must preserve the same contracts. See the standing rules in `AGENTS.md` and
`frontend/AGENTS.md`.
## Contribution workflow
Follow [`AGENTS.md`](AGENTS.md) and the applicable scoped guidelines, including
[`frontend/AGENTS.md`](frontend/AGENTS.md). Repository skills belong under
[`.agents/skills/`](.agents/skills).
Implementation work uses a Gitea task and linked branch, validation, commits,
a push and a PR. Merge only when authorized. Record scope, validation and known
limitations in the task and [implementation record](docs/implementation.md).
## Identity verification preview
Open `/#/identity` or use **Limits → Verify identity** in the workspace. The optional flow covers passport and selfie selection, review,
submission, pending review, approval, correction requests and denial in EN/RU.
Use sample images only: photos are never uploaded and drafts are not persisted.
The shared [sxchnge_kyc package](frontend/packages/sxchnge_kyc/README.md) provides
identity and limits services/providers for web and future mobile clients. Limits
are fetched through `LimitsProvider → LimitsService`; fixture amounts and simulated
review decisions demonstrate the future backend contract. Higher limits apply
only when returned by that service. Production review/storage/support and financial
authorization are not connected. See the [UX plan](docs/ux/kyc.md) for state, error,
privacy and measurement details.
## Exchange workspace preview
Choose **Explore your accounts** on login/email confirmation, or open `/#/accounts`.
Currency cards show only available funds. Select an account, then top up, exchange
or pay out through input → review → status. Review shows fees and actual debit and
credit; status explains where the money is, including processing and failed returns.
Activity, account balances and limits use one coherent demo ledger.
Settings owns English/Russian account language. Limits links to optional KYC;
no verification remains a valid account state with basic limits.
The shared [wallet package](frontend/packages/sxchnge_wallet/README.md) is reusable
by mobile clients. Transactions, rates, fees, recipients and profile storage are
explicitly simulated and reset on reload. No real money moves. See the
[workspace UX plan](docs/ux/exchange-workspace.md) and
[implementation record](docs/implementation.md) for scope and validation.
## Two-factor verification
Account **Settings → Two-factor verification** enables or disables protection
with a confirmed code. When enabled, login, top-ups, exchanges and payouts use a
shared SXCHNGE-themed challenge page. Money challenges retain the reviewed fees
and funds movement; cancelling preserves the transaction draft.
The initial service uses email-code fixtures: **123456** is the local test code.
No email is sent and settings reset on reload. Method-aware contracts and page
instructions also support authenticator challenges; actual TOTP enrollment,
validation and recovery remain backend integration work. See the
[two-factor UX contract](docs/ux/two-factor.md) and
[shared auth package](frontend/packages/sxchnge_auth/README.md).
## Backend integration plan
The [BFF architecture and Sendico service audit](docs/architecture/bff.md) defines
consumer identity, financial-provider boundaries, reusable components, contract
gaps and delivery phases. Selected Sendico code has been adapted with recorded
[provenance](backend/PROVENANCE.md); the projects share no runtime modules.
Run `make test-backend`, `make lint-backend` or `make run-backend` from the root.
The copied runtime installs local authentication transport and initializes its
account service. Signup/profile endpoints, verification delivery/completion,
Flutter HTTP adapters and live Sendico operations remain to be wired. See the
[backend run guide](backend/README.md) for local MongoDB configuration.