diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 76989b3..969ccd6 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -6,7 +6,7 @@ on: jobs: status-is-current: - name: STATUS.md matches the code + name: status.md matches the code runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 diff --git a/.xtask/src/main.rs b/.xtask/src/main.rs index adef4cb..abed27f 100644 --- a/.xtask/src/main.rs +++ b/.xtask/src/main.rs @@ -4,7 +4,7 @@ //! itself, because a promise nothing checks is a promise that decays: //! //! * `verify-no-mocks` — no test double is reachable from a shipping binary. -//! * `verify-status` — every `NotImplemented` is declared in `docs/STATUS.md`. +//! * `verify-status` — every `NotImplemented` is declared in `docs/status.md`. // This is a CLI; stdout is its output medium, not stray debugging. #![allow(clippy::print_stdout)] @@ -117,12 +117,12 @@ fn runtime_dependency_section(manifest: &str) -> String { out } -/// Fail if the code claims something is unbuilt that `docs/STATUS.md` does not +/// Fail if the code claims something is unbuilt that `docs/status.md` does not /// declare — or vice versa. Keeps the status page honest by construction. fn verify_status(root: &Path) -> Result<(), String> { - let status_path = root.join("docs/STATUS.md"); + let status_path = root.join("docs/status.md"); let status = fs::read_to_string(&status_path) - .map_err(|e| format!("docs/STATUS.md: {e} (the status page is mandatory)"))?; + .map_err(|e| format!("docs/status.md: {e} (the status page is mandatory)"))?; let mut found = BTreeSet::new(); for src in rust_sources(&root.join("backends")) { @@ -137,7 +137,7 @@ fn verify_status(root: &Path) -> Result<(), String> { let undeclared: Vec<_> = found.iter().filter(|t| !status.contains(*t)).collect(); if !undeclared.is_empty() { return Err(format!( - "these unimplemented items are missing from docs/STATUS.md:\n - {}", + "these unimplemented items are missing from docs/status.md:\n - {}", undeclared .iter() .map(|s| s.as_str()) @@ -147,7 +147,7 @@ fn verify_status(root: &Path) -> Result<(), String> { } println!( - "verify-status: ok — {} unimplemented item(s), all declared in docs/STATUS.md", + "verify-status: ok — {} unimplemented item(s), all declared in docs/status.md", found.len() ); Ok(()) diff --git a/AGENTS.md b/AGENTS.md index 66f4ca4..a7209fb 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -30,11 +30,11 @@ structurally possible. - Unwritten code returns `ProviderError::NotImplemented("::")`. It **never** returns a plausible-looking success, an empty list, or a zero. -- Every such token must appear in `docs/STATUS.md`. `cargo xtask verify-status` +- Every such token must appear in `docs/status.md`. `cargo xtask verify-status` fails the build otherwise — and it fails in both directions. - Tests for unbuilt behaviour are `#[ignore = "not implemented: … — see - docs/STATUS.md"]`, so a green run never overstates coverage. -- When you finish something, update `docs/STATUS.md` in the same commit. A + docs/status.md"]`, so a green run never overstates coverage. +- When you finish something, update `docs/status.md` in the same commit. A status page that lags is worse than none, because people trust it. If you are unsure whether something counts as done: would a test fail if it @@ -122,7 +122,7 @@ Each ends with a **Status** section stating what is actually built. ## Commits and PRs - Conventional commits (`feat:`, `fix:`, `docs:`, `chore:`, `refactor:`). -- A PR that changes behaviour updates `docs/STATUS.md` and the relevant flow doc +- A PR that changes behaviour updates `docs/status.md` and the relevant flow doc in the same PR. - `just ci` must pass locally before review. diff --git a/CLAUDE.md b/CLAUDE.md index 7c83b07..e8b57d9 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -8,10 +8,10 @@ is specific to working here as an agent. ```bash just verify # the two self-checks; both must pass before AND after your change -cat docs/STATUS.md +cat docs/status.md ``` -`docs/STATUS.md` tells you what is actually built. Do not infer capability from +`docs/status.md` tells you what is actually built. Do not infer capability from the presence of a file — most of this repo is scaffold, and it says so. ## The failure mode to avoid @@ -24,20 +24,20 @@ than it is: - writing a test that asserts nothing so a suite goes green, - adding a mock adapter to make local development easier, - rendering fake rows in the dashboard so a screenshot looks good, -- marking something ✅ in `docs/STATUS.md` because it compiles. +- marking something ✅ in `docs/status.md` because it compiles. Each of these is worse than leaving the gap visible. This is a payment system; someone will eventually trust it with real money on the strength of what the repo claims about itself. If you cannot implement something properly, leave -`ProviderError::NotImplemented`, list it in `docs/STATUS.md`, and say so plainly +`ProviderError::NotImplemented`, list it in `docs/status.md`, and say so plainly in your summary. ## When you finish a task 1. `just ci` -2. Update `docs/STATUS.md` — in the same commit, not a follow-up. +2. Update `docs/status.md` — in the same commit, not a follow-up. 3. Update the relevant `docs/flows/*.md` **Status** section. 4. In your summary to the user, state explicitly what you did **not** do. diff --git a/README.md b/README.md index 6bfaf03..365220a 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ MTN MoMo and Orange Money are the first two adapters. Neither is the architectur > This repository is a **scaffold**. It compiles, lints clean and its tests pass, > but **no HTTP call to any payment rail has ever been made by this code**. > -> Read [`docs/STATUS.md`](docs/STATUS.md) before forming any expectation of what +> Read [`docs/status.md`](docs/status.md) before forming any expectation of what > works. That page is machine-checked: `cargo xtask verify-status` fails the > build if the code contains an unimplemented path that the status page does not > declare. @@ -53,7 +53,7 @@ rail. `cargo xtask verify-no-mocks` enforces it. **2. Never claim a feature is done when it is not.** Unwritten code returns `ProviderError::NotImplemented` — it never fabricates a success. Every such path -must appear in `docs/STATUS.md`, and `cargo xtask verify-status` fails the build +must appear in `docs/status.md`, and `cargo xtask verify-status` fails the build otherwise. Tests for unbuilt features are `#[ignore]`d with a reason, so a green run never overstates coverage. @@ -69,8 +69,8 @@ frontends/ apps/ dashboard (Next.js) tests/ e2e (Cypress) examples/ merchant-curl · merchant-node · webhook-receiver -docs/ adr/ · rfc/ · flows/ · runbooks/ · api/ · STATUS.md -schemas/ *.cstack (syntax verified, design sketch, excluded from the build — see docs/STATUS.md) +docs/ adr/ · rfc/ · flows/ · runbooks/ · api/ · status.md +schemas/ *.cstack (syntax verified, design sketch, excluded from the build — see docs/status.md) .xtask/ repo automation and the two self-checks ``` @@ -122,7 +122,7 @@ Neither binary calls a payment rail. `vpay-server` writes rows and serves only its job loop is not implemented, and it says so in a startup banner and a repeating heartbeat log line. `--database-url`, `--config` and `--public-base-url` are accepted but not yet consumed by anything — see -[`docs/STATUS.md`](docs/STATUS.md) and +[`docs/status.md`](docs/status.md) and [`docs/flows/configuration.md`](docs/flows/configuration.md). ### Known environment gotchas @@ -139,11 +139,11 @@ repeating heartbeat log line. `--database-url`, `--config` and `just build-dist`. `backends/Dockerfile` now builds the host's *implicit* musl target rather than hardcoding the x86_64 triple, but the Dockerfiles themselves have not been built in this repo's own development environment — - see [`docs/STATUS.md`](docs/STATUS.md)'s Infrastructure section for why. + see [`docs/status.md`](docs/status.md)'s Infrastructure section for why. ## Documentation -Start with [`docs/STATUS.md`](docs/STATUS.md), then: +Start with [`docs/status.md`](docs/status.md), then: - [Flows](docs/flows/) — one document per process, with invariants - [ADRs](docs/adr/) — decisions and what they cost diff --git a/backends/apps/vpay-server/src/main.rs b/backends/apps/vpay-server/src/main.rs index cf35d31..c81859d 100644 --- a/backends/apps/vpay-server/src/main.rs +++ b/backends/apps/vpay-server/src/main.rs @@ -41,7 +41,7 @@ async fn main() -> anyhow::Result<()> { .await .with_context(|| format!("binding {}", args.bind))?; - tracing::warn!("vpay-server is a scaffold: only /healthz is implemented. See docs/STATUS.md"); + tracing::warn!("vpay-server is a scaffold: only /healthz is implemented. See docs/status.md"); tracing::info!(addr = %args.bind, "listening"); let shutdown_grace = Duration::from_secs(args.common.shutdown_grace_seconds); diff --git a/backends/apps/vpay-worker-bin/src/main.rs b/backends/apps/vpay-worker-bin/src/main.rs index ed6d9c9..427d6b3 100644 --- a/backends/apps/vpay-worker-bin/src/main.rs +++ b/backends/apps/vpay-worker-bin/src/main.rs @@ -1,6 +1,6 @@ //! vpay worker: submit, poll, reconcile, deliver. //! -//! The job loop itself is not implemented (`docs/STATUS.md`) — this process +//! The job loop itself is not implemented (`docs/status.md`) — this process //! supervises nothing yet. It used to exit immediately on start, on the //! theory that idling in a loop that did nothing would look like a running //! worker in `docker compose ps`. In practice that made the compose stack @@ -35,14 +35,14 @@ async fn main() -> anyhow::Result<()> { tracing::warn!( "vpay-worker-bin is a scaffold: the job loop is NOT implemented. No jobs \ are being dequeued, polled, or delivered. This process stays up only to \ - answer shutdown signals correctly. See docs/STATUS.md." + answer shutdown signals correctly. See docs/status.md." ); // `--shutdown-grace-seconds` / `VPAY_SHUTDOWN_GRACE_SECONDS` is parsed // and validated here (it is shared with `vpay-server` via // `CommonArgs`), but intentionally not consumed below: there is no // in-flight work for it to bound yet, because the job loop it is meant - // to bound the drain of does not exist (docs/STATUS.md). Once that loop + // to bound the drain of does not exist (docs/status.md). Once that loop // is implemented, this value should bound how long it waits for an // in-flight job to finish after a shutdown signal, the same way // `vpay-server`'s `main.rs` bounds its HTTP request drain. Wiring it in @@ -52,7 +52,7 @@ async fn main() -> anyhow::Result<()> { tracing::debug!( shutdown_grace_seconds = args.common.shutdown_grace_seconds, "shutdown grace period accepted for CLI parity with vpay-server; has no effect yet, \ - there is no job loop for it to bound (see docs/STATUS.md)" + there is no job loop for it to bound (see docs/status.md)" ); let mut heartbeat = tokio::time::interval(HEARTBEAT_INTERVAL); @@ -72,7 +72,7 @@ async fn main() -> anyhow::Result<()> { _ = heartbeat.tick() => { tracing::warn!( "vpay-worker-bin heartbeat: job loop still not implemented, no jobs \ - are being processed. See docs/STATUS.md." + are being processed. See docs/status.md." ); } } diff --git a/backends/crates/vpay-adapter-mtn-momo/src/lib.rs b/backends/crates/vpay-adapter-mtn-momo/src/lib.rs index 6385494..ec2b997 100644 --- a/backends/crates/vpay-adapter-mtn-momo/src/lib.rs +++ b/backends/crates/vpay-adapter-mtn-momo/src/lib.rs @@ -2,7 +2,7 @@ //! //! STATUS: capabilities are real and enforced; wire calls are NOT implemented. //! Every unimplemented method returns `ProviderError::NotImplemented` — it never -//! fabricates a success. See `docs/STATUS.md` and `docs/flows/adapter-mtn-momo.md`. +//! fabricates a success. See `docs/status.md` and `docs/flows/adapter-mtn-momo.md`. use vpay_core::{Money, ProviderFlow}; use vpay_provider::{ diff --git a/backends/crates/vpay-adapter-orange-money/src/lib.rs b/backends/crates/vpay-adapter-orange-money/src/lib.rs index a837edd..d329fce 100644 --- a/backends/crates/vpay-adapter-orange-money/src/lib.rs +++ b/backends/crates/vpay-adapter-orange-money/src/lib.rs @@ -2,7 +2,7 @@ //! //! STATUS: capabilities are real and enforced; wire calls are NOT implemented. //! Every unimplemented method returns `ProviderError::NotImplemented` — it never -//! fabricates a success. See `docs/STATUS.md` and `docs/flows/adapter-orange-money.md`. +//! fabricates a success. See `docs/status.md` and `docs/flows/adapter-orange-money.md`. use vpay_core::{Money, ProviderFlow}; use vpay_provider::{ diff --git a/backends/crates/vpay-api/src/lib.rs b/backends/crates/vpay-api/src/lib.rs index 9847953..3c93b46 100644 --- a/backends/crates/vpay-api/src/lib.rs +++ b/backends/crates/vpay-api/src/lib.rs @@ -1,7 +1,7 @@ //! The Stripe-shaped HTTP surface. //! //! STATUS: only `/healthz` and the Stripe-shaped 404 envelope are implemented. -//! No `/v1/*` route exists yet. See `docs/STATUS.md` — this file must never +//! No `/v1/*` route exists yet. See `docs/status.md` — this file must never //! grow a route that returns fabricated data. use axum::{Json, Router, http::StatusCode, routing::get}; diff --git a/backends/crates/vpay-config/src/cli.rs b/backends/crates/vpay-config/src/cli.rs index 4fbab78..188f829 100644 --- a/backends/crates/vpay-config/src/cli.rs +++ b/backends/crates/vpay-config/src/cli.rs @@ -43,7 +43,7 @@ pub struct CommonArgs { /// Postgres connection string. /// /// Accepted and threaded through even though the database layer is not - /// implemented yet (`docs/STATUS.md`) — the wiring exists so turning the + /// implemented yet (`docs/status.md`) — the wiring exists so turning the /// layer on later is a matter of using this value, not inventing a new /// flag. #[arg(long, env = "DATABASE_URL")] @@ -59,7 +59,7 @@ pub struct CommonArgs { /// Path to the YAML configuration file (ADR-0003). /// /// Optional because figment layering / file loading is not implemented - /// yet (`docs/STATUS.md`). + /// yet (`docs/status.md`). #[arg(long, env = "VPAY_CONFIG")] pub config: Option, @@ -79,7 +79,7 @@ pub struct CommonArgs { /// before the process stops waiting and exits (see `main.rs`). /// `vpay-worker-bin` accepts and validates this same flag for parity /// across binaries, but has no in-flight work to bound yet — the job - /// loop is not implemented (`docs/STATUS.md`) — so today it has no + /// loop is not implemented (`docs/status.md`) — so today it has no /// effect there. #[arg(long, env = "VPAY_SHUTDOWN_GRACE_SECONDS", default_value_t = 25)] pub shutdown_grace_seconds: u64, @@ -93,7 +93,7 @@ pub struct CommonArgs { about = "vpay payment gateway API server", long_about = "vpay payment gateway API server.\n\nWrites rows and returns; it never calls a payment rail itself \ (see docs/flows). This binary is a scaffold — run with --help \ - to see the full flag set, and see docs/STATUS.md for what is \ + to see the full flag set, and see docs/status.md for what is \ actually implemented behind it." )] pub struct ServerArgs { @@ -119,7 +119,7 @@ pub struct ServerArgs { version, about = "vpay background worker", long_about = "vpay background worker: submit, poll, reconcile, deliver.\n\nThe job \ - loop is not implemented yet (docs/STATUS.md) — this process stays up \ + loop is not implemented yet (docs/status.md) — this process stays up \ and answers shutdown signals so orchestration (docker compose, k8s) \ behaves correctly around it, but it processes no jobs." )] diff --git a/backends/crates/vpay-config/src/lib.rs b/backends/crates/vpay-config/src/lib.rs index 220de94..edbe5be 100644 --- a/backends/crates/vpay-config/src/lib.rs +++ b/backends/crates/vpay-config/src/lib.rs @@ -4,7 +4,7 @@ //! never select a *code path*. See `docs/adr/0003-yaml-configuration.md`. //! //! STATUS: types and the deployment guard rules are implemented and tested. -//! Figment layering and DB reconciliation are NOT implemented — `docs/STATUS.md`. +//! Figment layering and DB reconciliation are NOT implemented — `docs/status.md`. use serde::{Deserialize, Serialize}; diff --git a/backends/crates/vpay-ledger/src/lib.rs b/backends/crates/vpay-ledger/src/lib.rs index e108727..ea959b2 100644 --- a/backends/crates/vpay-ledger/src/lib.rs +++ b/backends/crates/vpay-ledger/src/lib.rs @@ -5,7 +5,7 @@ //! merchant received. See `docs/flows/ledger.md`. //! //! STATUS: types and the balancing invariant are implemented and tested. -//! Persistence is NOT implemented — see `docs/STATUS.md`. +//! Persistence is NOT implemented — see `docs/status.md`. use vpay_core::{Money, MoneyError}; diff --git a/backends/crates/vpay-provider/src/lib.rs b/backends/crates/vpay-provider/src/lib.rs index e8b69ce..0cf96d6 100644 --- a/backends/crates/vpay-provider/src/lib.rs +++ b/backends/crates/vpay-provider/src/lib.rs @@ -99,7 +99,7 @@ pub enum ProviderError { #[error("operation not supported by this rail")] Unsupported, /// Not yet built. This is NOT a mock: it never pretends to succeed. - /// Every occurrence must appear in `docs/STATUS.md`. + /// Every occurrence must appear in `docs/status.md`. #[error("not implemented yet: {0}")] NotImplemented(&'static str), } diff --git a/backends/crates/vpay-worker/src/lib.rs b/backends/crates/vpay-worker/src/lib.rs index 10d91cf..95bb89c 100644 --- a/backends/crates/vpay-worker/src/lib.rs +++ b/backends/crates/vpay-worker/src/lib.rs @@ -3,7 +3,7 @@ //! Everything that touches the network happens here, never in the API process. //! //! STATUS: only the poll ladder is implemented and tested. Job dequeue, -//! submission and delivery are NOT implemented — see `docs/STATUS.md`. +//! submission and delivery are NOT implemented — see `docs/status.md`. use std::time::Duration; diff --git a/backends/tests/conformance/tests/adapter_conformance.rs b/backends/tests/conformance/tests/adapter_conformance.rs index df48284..35b42c4 100644 --- a/backends/tests/conformance/tests/adapter_conformance.rs +++ b/backends/tests/conformance/tests/adapter_conformance.rs @@ -6,7 +6,7 @@ //! //! STATUS: only capability-level cases run today. The wire-level cases are //! `#[ignore]`d with a reason until the adapters exist, so a green run never -//! overstates coverage. See docs/STATUS.md. +//! overstates coverage. See docs/status.md. use vpay_provider::{Capabilities, ProviderAdapter, ProviderError}; @@ -66,19 +66,19 @@ fn unimplemented_operations_never_fabricate_success() { // --------------------------------------------------------------------------- #[test] -#[ignore = "not implemented: submit() — see docs/STATUS.md"] +#[ignore = "not implemented: submit() — see docs/status.md"] fn duplicate_submit_reports_submitted_not_an_error() { unreachable!("enable when submit() lands") } #[test] -#[ignore = "not implemented: query_status() — see docs/STATUS.md"] +#[ignore = "not implemented: query_status() — see docs/status.md"] fn not_found_is_never_on_its_own_a_failure() { unreachable!("enable when query_status() lands") } #[test] -#[ignore = "not implemented: redirect flow — see docs/STATUS.md"] +#[ignore = "not implemented: redirect flow — see docs/status.md"] fn redirect_rails_commit_ref_extra_before_returning_a_url() { unreachable!("enable when the Orange adapter lands") } diff --git a/backends/tests/integration/tests/postgres_smoke.rs b/backends/tests/integration/tests/postgres_smoke.rs index f934e15..3519856 100644 --- a/backends/tests/integration/tests/postgres_smoke.rs +++ b/backends/tests/integration/tests/postgres_smoke.rs @@ -4,13 +4,13 @@ //! and is `#[ignore]`d so it cannot report false confidence. #[test] -#[ignore = "not implemented: testcontainers harness — see docs/STATUS.md"] +#[ignore = "not implemented: testcontainers harness — see docs/status.md"] fn schema_migrates_cleanly_on_an_empty_database() { unreachable!("enable when migrations land") } #[test] -#[ignore = "not implemented: testcontainers harness — see docs/STATUS.md"] +#[ignore = "not implemented: testcontainers harness — see docs/status.md"] fn one_charge_per_intent_is_enforced_by_the_database() { unreachable!("enable when migrations land") } diff --git a/compose.e2e.yml b/compose.e2e.yml index fb982c7..b61d69f 100644 --- a/compose.e2e.yml +++ b/compose.e2e.yml @@ -65,7 +65,7 @@ services: # healthcheck to report healthy (see the comment above it). This is a # boot-order guarantee only — the dashboard can still start before the # server has finished binding its listener. That race is currently - # harmless: per docs/STATUS.md the dashboard renders a static scaffold + # harmless: per docs/status.md the dashboard renders a static scaffold # notice and makes no server-side call to `vpay-server` yet. Revisit # this once the dashboard actually calls `/dash/v1` on render. vpay-server: { condition: service_started } diff --git a/docs/api/README.md b/docs/api/README.md index ca9a12a..a38874a 100644 --- a/docs/api/README.md +++ b/docs/api/README.md @@ -8,7 +8,7 @@ Authenticated with `sk_live_` / `sk_test_` keys. Form-encoded bodies, Stripe's object model, Stripe's error envelope, Stripe's idempotency semantics. **Status: not implemented.** Only `/healthz` and a Stripe-shaped 404 exist. See -[../STATUS.md](../STATUS.md). +[../status.md](../status.md). Planned subset: diff --git a/docs/flows/README.md b/docs/flows/README.md index 52895da..0a613b1 100644 --- a/docs/flows/README.md +++ b/docs/flows/README.md @@ -17,5 +17,5 @@ go wrong, and what invariant holds throughout. | [adapter-mtn-momo.md](adapter-mtn-momo.md) | MTN specifics — push flow | | [adapter-orange-money.md](adapter-orange-money.md) | Orange specifics — redirect flow | -Every flow here is *designed*. See [../STATUS.md](../STATUS.md) for which parts +Every flow here is *designed*. See [../status.md](../status.md) for which parts are actually built. diff --git a/docs/flows/adapter-mtn-momo.md b/docs/flows/adapter-mtn-momo.md index c531e60..b46ba1b 100644 --- a/docs/flows/adapter-mtn-momo.md +++ b/docs/flows/adapter-mtn-momo.md @@ -78,4 +78,4 @@ never treat 500 as blind-retry. ## Status Capabilities are declared and tested. **No wire call is implemented** — see -[../STATUS.md](../STATUS.md). +[../status.md](../status.md). diff --git a/docs/flows/adapter-orange-money.md b/docs/flows/adapter-orange-money.md index 524ca2b..9b0f7a2 100644 --- a/docs/flows/adapter-orange-money.md +++ b/docs/flows/adapter-orange-money.md @@ -85,4 +85,4 @@ method, not a core change. ## Status Capabilities are declared and tested. **No wire call is implemented** — see -[../STATUS.md](../STATUS.md). +[../status.md](../status.md). diff --git a/docs/flows/configuration.md b/docs/flows/configuration.md index 2a97d09..03afb8c 100644 --- a/docs/flows/configuration.md +++ b/docs/flows/configuration.md @@ -39,7 +39,7 @@ shutdown signal, via `serve_with_bounded_drain` in of that length and exits non-zero if the clock wins. `vpay-worker-bin` accepts and logs the same flag but does nothing with it; there is no drain to bound because there is no job loop yet. Neither binary's handling of the *timeout* -case is covered by a test today — see [../STATUS.md](../STATUS.md). +case is covered by a test today — see [../status.md](../status.md). ## There is no sandbox mode @@ -67,7 +67,7 @@ behave differently*. boot sequence that actually exists. Nothing in this repo loads a YAML file, resolves a `${}` placeholder, runs the validation rules below, or reconciles anything into a database, because there is no database layer yet -(`docs/STATUS.md`). The steps below describe the design this repo is building +(`docs/status.md`). The steps below describe the design this repo is building towards, not current behaviour. 1. Load `application.yml`, overlay `application-{profile}.yml`. @@ -138,4 +138,4 @@ accepted but inert on `vpay-worker-bin`. **Not started:** everything else in the "Boot sequence" above — YAML loading, `${}` placeholder resolution, validation wired into boot, and database reconciliation. `--database-url` and `--config` are accepted CLI/env inputs -with nothing behind them yet. See [../STATUS.md](../STATUS.md). +with nothing behind them yet. See [../status.md](../status.md). diff --git a/docs/flows/crash-safety.md b/docs/flows/crash-safety.md index e77cf27..b58a1b7 100644 --- a/docs/flows/crash-safety.md +++ b/docs/flows/crash-safety.md @@ -91,4 +91,4 @@ before any `provider_requests` row; after that row and before the response; after the response and before the state update — and assert the recovery table resolves all three without double-charging. -**Status: not implemented.** See [../STATUS.md](../STATUS.md). +**Status: not implemented.** See [../status.md](../status.md). diff --git a/docs/flows/failures.md b/docs/flows/failures.md index 0093d96..15feaeb 100644 --- a/docs/flows/failures.md +++ b/docs/flows/failures.md @@ -31,4 +31,4 @@ Each adapter's mapping lives in its own flow doc: ## Status The taxonomy is implemented and tested (`vpay-core::failure`). Neither adapter's -mapping is implemented — see [../STATUS.md](../STATUS.md). +mapping is implemented — see [../status.md](../status.md). diff --git a/docs/flows/ledger.md b/docs/flows/ledger.md index a0a4e0b..dec8322 100644 --- a/docs/flows/ledger.md +++ b/docs/flows/ledger.md @@ -81,4 +81,4 @@ Invariant 1 is implemented and tested in `vpay-ledger` (`a_capture_with_a_fee_balances`, `an_unbalanced_transaction_is_rejected`). **Persistence and invariants 2–4 are not started**, and invariant 2 additionally cannot be computed from the current `AccountKind` type as noted above — see -[../STATUS.md](../STATUS.md). +[../status.md](../status.md). diff --git a/docs/flows/payment-lifecycle.md b/docs/flows/payment-lifecycle.md index 45dbaca..3983299 100644 --- a/docs/flows/payment-lifecycle.md +++ b/docs/flows/payment-lifecycle.md @@ -78,4 +78,4 @@ noticeably from Stripe's ergonomics, and it is deliberate. Types and the flow-selection logic are implemented and tested (`vpay-core::state`). No transition is driven by real data yet — see -[../STATUS.md](../STATUS.md). +[../status.md](../status.md). diff --git a/docs/flows/reconciler.md b/docs/flows/reconciler.md index 81b83f7..491d156 100644 --- a/docs/flows/reconciler.md +++ b/docs/flows/reconciler.md @@ -57,4 +57,4 @@ The `dedupe_key` is what stops duplicate callbacks becoming a job storm. ## Status `poll_delay` is implemented and tested. The job loop, the escalation and the -callback endpoint are **not started** — see [../STATUS.md](../STATUS.md). +callback endpoint are **not started** — see [../status.md](../status.md). diff --git a/docs/flows/webhooks.md b/docs/flows/webhooks.md index 67c5322..d6f835e 100644 --- a/docs/flows/webhooks.md +++ b/docs/flows/webhooks.md @@ -41,4 +41,4 @@ Delivery is at-least-once; merchants must dedupe by `event.id`. ## Status -**Not started.** See [../STATUS.md](../STATUS.md). +**Not started.** See [../status.md](../status.md). diff --git a/docs/runbooks/README.md b/docs/runbooks/README.md index 10407a8..6e63b57 100644 --- a/docs/runbooks/README.md +++ b/docs/runbooks/README.md @@ -9,4 +9,4 @@ do, and how do I know it is fixed. | [provider-error-rate.md](provider-error-rate.md) | `provider_error` rate rising | **Status:** written from the design, never exercised against a running system. -See [../STATUS.md](../STATUS.md). +See [../status.md](../status.md). diff --git a/docs/STATUS.md b/docs/status.md similarity index 98% rename from docs/STATUS.md rename to docs/status.md index 3c9d5cc..336e1e7 100644 --- a/docs/STATUS.md +++ b/docs/status.md @@ -91,7 +91,7 @@ makes the core refuse a refund on that rail. | `@vpay/tokens` status tokens | ✅ | 3 tests incl. "success tone belongs to `succeeded` alone" | | `@vpay/ui` `StatusBadge` (cva + daisyUI) | ✅ | 3 tests | | `@vpay/ui` `PayerSheet` (vaul + framer-motion) | 🟡 | Renders; **no test** — needs interaction coverage | -| `@vpay/ui` production build (`next build`) | ✅ | Was broken: relative imports used a `.js` suffix (`'./cn.js'`); `moduleResolution: "bundler"` let `tsc`/Vitest resolve that back to the `.ts` source, so both passed while Next's webpack resolver took the suffix literally and failed with `Module not found`. Suffixes were dropped from `frontends/packages/ui/src/index.ts`, `StatusBadge.tsx` and `PayerSheet.tsx`; `pnpm -r build` now compiles all packages including the dashboard's `next build` | +| `@vpay/ui` production build (`next build`) | ✅ | Was broken: relative imports used a `.js` suffix (`'./cn.js'`); `moduleResolution: "bundler"` let `tsc`/Vitest resolve that back to the `.ts` source, so both passed while Next's webpack resolver took the suffix literally and failed with `Module not found`. Suffixes were dropped from `frontends/packages/ui/src/index.ts`, `status-badge.tsx` and `payer-sheet.tsx`; `pnpm -r build` now compiles all packages including the dashboard's `next build` | | Storybook | 🟡 | Configured with a11y addon; **only `StatusBadge` has stories** | | `@vpay/api-client` | 🟡 | `formatAmount` done + 4 tests. **Every network call throws `NotImplementedError`** | | Dashboard app | 🟡 | Renders a scaffold notice and a design-system smoke test. **No data, no auth, no routes** | diff --git a/examples/README.md b/examples/README.md index 120e9b5..417eadf 100644 --- a/examples/README.md +++ b/examples/README.md @@ -10,4 +10,4 @@ Runnable merchant-side integrations. **Status:** these describe the *intended* API. `/v1/*` is not implemented, so none of them will succeed against a running vpay today. See -[../docs/STATUS.md](../docs/STATUS.md). +[../docs/status.md](../docs/status.md). diff --git a/examples/merchant-curl/README.md b/examples/merchant-curl/README.md index 4504cff..516e57e 100644 --- a/examples/merchant-curl/README.md +++ b/examples/merchant-curl/README.md @@ -1,6 +1,6 @@ # Raw HTTP -> Not runnable yet — `/v1/*` is not implemented. See ../../docs/STATUS.md. +> Not runnable yet — `/v1/*` is not implemented. See ../../docs/status.md. ## Create a PaymentIntent diff --git a/examples/merchant-node/index.mjs b/examples/merchant-node/index.mjs index 9769253..cb40cf3 100644 --- a/examples/merchant-node/index.mjs +++ b/examples/merchant-node/index.mjs @@ -1,7 +1,7 @@ /** * Pointing the official Stripe SDK at a vpay host. * - * NOT RUNNABLE YET — /v1/* is not implemented. See ../../docs/STATUS.md. + * NOT RUNNABLE YET — /v1/* is not implemented. See ../../docs/status.md. * * This file exists to pin down the compatibility claim: if this script ever * needs a vpay-specific workaround, the API is not Stripe-shaped enough. diff --git a/examples/webhook-receiver/index.mjs b/examples/webhook-receiver/index.mjs index 04df69f..59a9b69 100644 --- a/examples/webhook-receiver/index.mjs +++ b/examples/webhook-receiver/index.mjs @@ -4,7 +4,7 @@ * The scheme is Stripe's, so if you already verify Stripe webhooks this is the * same code with a different header name. * - * vpay does not send webhooks yet (see ../../docs/STATUS.md), but the + * vpay does not send webhooks yet (see ../../docs/status.md), but the * verification below is complete and correct — copy it. */ import { createHmac, timingSafeEqual } from 'node:crypto'; diff --git a/frontends/apps/dashboard/app/page.tsx b/frontends/apps/dashboard/app/page.tsx index 9335d1a..29232dc 100644 --- a/frontends/apps/dashboard/app/page.tsx +++ b/frontends/apps/dashboard/app/page.tsx @@ -15,7 +15,7 @@ export default function Home() {
Scaffold. No data source is connected — /dash/v1 is not - implemented. See docs/STATUS.md. + implemented. See docs/status.md.
diff --git a/frontends/packages/api-client/src/index.ts b/frontends/packages/api-client/src/index.ts index f1fd3bb..5172ad7 100644 --- a/frontends/packages/api-client/src/index.ts +++ b/frontends/packages/api-client/src/index.ts @@ -5,7 +5,7 @@ * API). The dashboard authenticates with an OIDC session, never a merchant * secret key — see docs/adr/0008-dashboard-scope.md. * - * STATUS: types only. No request is issued yet; see docs/STATUS.md. + * STATUS: types only. No request is issued yet; see docs/status.md. */ import type { PaymentStatus } from '@vpay/tokens'; @@ -22,7 +22,7 @@ export interface PaymentIntentView { export class NotImplementedError extends Error { constructor(what: string) { - super(`${what} is not implemented — see docs/STATUS.md`); + super(`${what} is not implemented — see docs/status.md`); this.name = 'NotImplementedError'; } } diff --git a/frontends/packages/ui/src/components/PayerSheet.tsx b/frontends/packages/ui/src/components/payer-sheet.tsx similarity index 100% rename from frontends/packages/ui/src/components/PayerSheet.tsx rename to frontends/packages/ui/src/components/payer-sheet.tsx diff --git a/frontends/packages/ui/src/components/StatusBadge.stories.tsx b/frontends/packages/ui/src/components/status-badge.stories.tsx similarity index 94% rename from frontends/packages/ui/src/components/StatusBadge.stories.tsx rename to frontends/packages/ui/src/components/status-badge.stories.tsx index 3a15a06..941c2a6 100644 --- a/frontends/packages/ui/src/components/StatusBadge.stories.tsx +++ b/frontends/packages/ui/src/components/status-badge.stories.tsx @@ -1,7 +1,7 @@ import type { Meta, StoryObj } from '@storybook/react'; import { PAYMENT_STATUS } from '@vpay/tokens'; -import { StatusBadge } from './StatusBadge.js'; +import { StatusBadge } from './status-badge.js'; const meta = { title: 'Payments/StatusBadge', diff --git a/frontends/packages/ui/src/components/StatusBadge.test.tsx b/frontends/packages/ui/src/components/status-badge.test.tsx similarity index 95% rename from frontends/packages/ui/src/components/StatusBadge.test.tsx rename to frontends/packages/ui/src/components/status-badge.test.tsx index 3e1b012..3747971 100644 --- a/frontends/packages/ui/src/components/StatusBadge.test.tsx +++ b/frontends/packages/ui/src/components/status-badge.test.tsx @@ -2,7 +2,7 @@ import { render, screen } from '@testing-library/react'; import { PAYMENT_STATUS, statusLabel } from '@vpay/tokens'; import { describe, expect, it } from 'vitest'; -import { StatusBadge } from './StatusBadge.js'; +import { StatusBadge } from './status-badge.js'; describe('StatusBadge', () => { it('renders the shared label for every status', () => { diff --git a/frontends/packages/ui/src/components/StatusBadge.tsx b/frontends/packages/ui/src/components/status-badge.tsx similarity index 100% rename from frontends/packages/ui/src/components/StatusBadge.tsx rename to frontends/packages/ui/src/components/status-badge.tsx diff --git a/frontends/packages/ui/src/index.ts b/frontends/packages/ui/src/index.ts index 3d94e5c..d7aa8bc 100644 --- a/frontends/packages/ui/src/index.ts +++ b/frontends/packages/ui/src/index.ts @@ -1,3 +1,3 @@ export { cn } from './cn'; -export { StatusBadge, type StatusBadgeProps } from './components/StatusBadge'; -export { PayerSheet, type PayerSheetProps } from './components/PayerSheet'; +export { StatusBadge, type StatusBadgeProps } from './components/status-badge'; +export { PayerSheet, type PayerSheetProps } from './components/payer-sheet'; diff --git a/justfile b/justfile index 386a056..3d1c724 100644 --- a/justfile +++ b/justfile @@ -2,7 +2,7 @@ # # Two invariants this repo enforces on itself, both wired into `just verify`: # * no test double is reachable from a shipping binary -# * every unimplemented item is declared in docs/STATUS.md +# * every unimplemented item is declared in docs/status.md set shell := ["bash", "-uc"] @@ -120,4 +120,4 @@ dev-dashboard: # Fail if a doc links to a file that does not exist. docs-check: cargo xtask verify-status - @echo "note: link checking is not implemented yet — see docs/STATUS.md" + @echo "note: link checking is not implemented yet — see docs/status.md" diff --git a/schemas/vpay.cstack b/schemas/vpay.cstack index 93b1b3f..a802134 100644 --- a/schemas/vpay.cstack +++ b/schemas/vpay.cstack @@ -19,7 +19,7 @@ // │ overview page. It does NOT prove a working migration or a running │ // │ server: this file is still EXCLUDED FROM THE BUILD GRAPH. No crate │ // │ depends on it, `cratestack migrate diff` has never been run against a │ -// │ real vpay Postgres, and `docs/STATUS.md` still lists the database │ +// │ real vpay Postgres, and `docs/status.md` still lists the database │ // │ schema itself as not started. Wiring it in is separate future work. │ // │ │ // │ One more thing this rewrite had to learn the hard way: `cratestack │ @@ -36,7 +36,7 @@ // │ provider_requests, webhook events/endpoints, the job queue, idempotency │ // │ keys, and Merchant. The "GAP" comments below explain exactly what's │ // │ missing and why it was left out rather than invented. See │ -// │ docs/STATUS.md for the authoritative done/not-done list. │ +// │ docs/status.md for the authoritative done/not-done list. │ // └──────────────────────────────────────────────────────────────────────────┘ datasource db { @@ -234,7 +234,7 @@ model Charge { // --- ledger ------------------------------------------------------------ // Mirrors backends/crates/vpay-ledger/src/lib.rs field-for-field. That // crate's types and its balancing invariant ARE implemented and tested -// (docs/STATUS.md: "🟡 Types and validate() done + 3 tests. Persistence not +// (docs/status.md: "🟡 Types and validate() done + 3 tests. Persistence not // started") — unlike provider_requests/webhooks/jobs above, there is real, // tested Rust code this half of the file mirrors, which is the line this // rewrite draws between "design sketch of a tested type" and "invented @@ -285,7 +285,7 @@ model LedgerEntry { // --- intentionally not modeled ------------------------------------------ // // The following are named in docs/flows/*.md and marked ⛔ "not started" in -// docs/STATUS.md, with zero corresponding Rust struct anywhere in +// docs/status.md, with zero corresponding Rust struct anywhere in // backends/crates/*/src (checked by grep for each name below). Modeling // their column shapes from doc prose alone would be inventing a plausible // schema for code that does not exist — the exact failure mode this file @@ -294,7 +294,7 @@ model LedgerEntry { // - webhook endpoints, the event/outbox pair, and webhook_delivery // (docs/flows/webhooks.md's two-step outbox — fanout_state, retries) // - the job queue and its dedupe_key (docs/flows/reconciler.md) -// - idempotency keys (docs/STATUS.md: ⛔, no design doc field list either) +// - idempotency keys (docs/status.md: ⛔, no design doc field list either) // - Merchant (referenced only as a bare merchant_id string everywhere // above — see the GAP note on PaymentIntent.merchant_id) //