0af35d44f4
Provide the production foundation for Apple identity, immutable credits, referrals, integrity checks, managed providers, and hardened Docker deployment.
73 lines
4.7 KiB
Plaintext
73 lines
4.7 KiB
Plaintext
OSGAccountServer is a private backend for OSGKeyboard.
|
|
|
|
- Use Kotlin 2.1+ with Ktor 3 and JDK 21.
|
|
- Organize code by business feature.
|
|
- Route handlers only validate and map HTTP.
|
|
- Services own business rules; repositories own persistence.
|
|
- Use constructor injection and explicit interfaces at external boundaries.
|
|
- Never log credentials, Apple subjects, audio, prompts, transcripts, or model output.
|
|
- Store monetary-like credit values as integers and use immutable ledger entries.
|
|
- Require idempotency for credit grants, reservations, settlement, refunds, and StoreKit events.
|
|
- Keep BYOK and local OSGKeyboard features independent from this service.
|
|
- Apply SOLID, DRY, KISS, YAGNI, and OWASP guidance.
|
|
- Add tests for success, failure, replay, concurrency, and boundary conditions.
|
|
- Do not commit secrets or production identifiers beyond public bundle/domain names.
|
|
# OSGAccountServer engineering rules
|
|
|
|
- Use Kotlin 2.1.20+, Ktor 3, JDK 21 and Gradle Kotlin DSL.
|
|
- Organize code by business feature under `features/`.
|
|
- Keep route handlers limited to request/response mapping.
|
|
- Put business rules in services and persistence in repositories.
|
|
- Use constructor injection and small, testable interfaces.
|
|
- Follow SOLID, DRY, KISS, YAGNI and OWASP guidance.
|
|
- Never log credentials, Apple identifiers, audio, prompts, transcripts or model output.
|
|
- Never store provider API keys in source control or container images.
|
|
- Use integer credits. Never use floating point for balances or billing.
|
|
- Credit mutations must be transactional, append-only and idempotent.
|
|
- Provider failures must release reserved credits; balances must never become negative.
|
|
- Sign in with Apple tokens must be verified server-side, including signature, issuer,
|
|
audience, expiry and nonce.
|
|
- Existing referral rewards require a qualified usage event; registration alone is not
|
|
sufficient for the main reward.
|
|
- Public APIs require validation, rate limiting and stable error codes.
|
|
- Database migrations are immutable after release.
|
|
- Tests must cover success, failure, replay, concurrency and boundary conditions.
|
|
- Do not expose MySQL or internal admin routes to the public network.
|
|
# OSGAccountServer
|
|
|
|
- Use Kotlin 2.1+ with JDK 21, Ktor, kotlinx.serialization, Exposed, HikariCP, Koin, and Kotest.
|
|
- Organize code by business feature under `features/`; keep routes thin, business logic in services, and persistence behind repositories.
|
|
- Apply SOLID, DRY, KISS, YAGNI, and OWASP practices.
|
|
- Store money-like credits as integer units and update balances only through immutable, idempotent ledger transactions.
|
|
- Never log tokens, Apple subjects, provider credentials, audio, prompts, transcripts, or generated responses.
|
|
- Keep all external providers behind interfaces and use deterministic fakes in tests.
|
|
- Require tests for success, validation, replay, concurrency, timeout, and failure/refund paths.
|
|
- Do not add a dependency unless the standard library or existing stack cannot solve the problem clearly.
|
|
# OSGAccountServer
|
|
|
|
- Use Kotlin 2.1+ with Ktor 3, JDK 21, and Gradle Kotlin DSL.
|
|
- Organize code by business feature: auth, account, credits, referrals, integrity, gateway.
|
|
- Keep routes limited to transport concerns; put business rules in services and persistence in repositories.
|
|
- Use constructor injection and interfaces at every external boundary.
|
|
- Follow SOLID, DRY, KISS, YAGNI, and OWASP guidance.
|
|
- Store no audio, prompts, transcripts, or generated response bodies.
|
|
- Never log secrets, Apple subjects, credentials, tokens, or user content.
|
|
- Keep all credit amounts as integers. Ledger rows are immutable and all writes are idempotent.
|
|
- Use database transactions and row locks for balance, reservation, settlement, and referral rewards.
|
|
- Require tests for success, failure, replay, concurrency, boundary, and provider-timeout paths.
|
|
- Keep public APIs versioned and document them in OpenAPI before mobile integration.
|
|
- Do not commit environment files, private keys, provider credentials, or production identifiers.
|
|
# OSGAccountServer
|
|
|
|
- Use Kotlin 2.1.20 or newer, Ktor 3, JDK 21, and Gradle Kotlin DSL.
|
|
- Organize code by business feature under `features/`.
|
|
- Route handlers only validate transport input and produce responses.
|
|
- Services own business rules; repositories own database access.
|
|
- Use constructor injection and explicit interfaces at external boundaries.
|
|
- Store money-like credits as integers and preserve an immutable ledger.
|
|
- Make every externally retried mutation idempotent.
|
|
- Never log tokens, Apple subjects, audio, prompts, transcripts, or model responses.
|
|
- Keep provider credentials and signing keys in environment-backed secret storage.
|
|
- Follow SOLID, DRY, KISS, YAGNI, and OWASP guidance.
|
|
- Add tests for success, validation, replay, concurrency, timeout, and rollback paths.
|