feat: add explicit Red MicoPay provider enrollment and fail-closed discovery - #373
feat: add explicit Red MicoPay provider enrollment and fail-closed discovery#373sasasamaes wants to merge 3 commits into
Conversation
Add provider_status enum (not_enrolled, pending_verification, active, suspended) to users table so account creation, Red MicoPay membership, verification and commercial availability are represented independently. - New users start as not_enrolled + unavailable (merchant_available=false) - POST /providers/enroll: idempotent enrollment endpoint - GET /providers/readiness: reports profile/location/limits/KYC completeness - Discovery filters only active + online + non-suspended providers - Availability updates reject non-active providers - pauseUser/unpauseUser write availability + merchant_available atomically - getOrCreateMerchantConfig blocks auto-creation for not_enrolled users - Demo seed data explicitly creates active providers - Migration backfills existing users to not_enrolled (safe: no real prod users) Closes Micopay#371
|
@sasasamaes Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits. You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀 |
|
Good structure overall. The separation of the four facts — account, enrollment, Blocker 1 — does
|
- Blocker 1: add missing is_banned column via new migration (auth, abuse, merchant, admin all reference it) - Blocker 2: add POST /providers/activate endpoint (pending_verification → active) with server-side readiness re-check - Small 1: ALTER COLUMN merchant_available SET DEFAULT false in enrollment migration for existing DBs - Small 2: unpauseUser only restores merchant_available for active providers - Small 3: IF NOT EXISTS guard on chk_provider_status constraint
|
Resolved in
Anything else to adjust? |
|
Thanks for the fast turnaround. Both blockers from the previous round are genuinely closed:
Three things still block the merge. The first one was already present in Blocker 1 — a fresh database can no longer be created
CREATE INDEX idx_users_provider_active
ON users (provider_status, availability, merchant_available)
WHERE provider_status = 'active';But the ALTER TABLE users
ADD COLUMN IF NOT EXISTS availability VARCHAR(16) NOT NULL DEFAULT 'online',
The simplest fix is to delete the index from Blocker 2 — the unpause test now contradicts the code it tests
merchant_available = CASE WHEN provider_status = 'active' THEN true ELSE merchant_available END,but strictEqual(after?.merchant_available, true, "unpaused merchant_available must be true");
Please seed the user as Blocker 3 — the fail-closed discovery tests are still vacuousThis was in the previous review and is unchanged. The comment above them is candid about why (the in-memory shim's WHERE regex matches the first literal Two ways out, either is fine:
If neither is practical in this PR, please collapse the five into one honest test named for what it actually checks ( Non-blocking
The readiness block is duplicated verbatim. The user/config/KYC lookups and the Constraint naming. |
- Remove partial index from init.sql (Blocker 1): idx_users_provider_active referenced availability column before it exists; migration already creates it with IF NOT EXISTS after the column is added. - Fix unpause tests for provider_status (Blocker 2): seedUsers() now sets provider_status='active' so the CASE WHEN guard is exercised. Added testUnpauseNotEnrolledStaysFalse to verify not_enrolled users keep merchant_available=false. In-memory shim limitation gracefully handled. - Make discovery fail-closed tests SQL-aware (Blocker 3): Tests now capture the SQL text passed to db.getMany and assert that eligibility predicates (provider_status, availability, is_suspended, is_banned, merchant_available) are present in the WHERE clause, instead of just checking result length.
|
Thanks for the thorough follow-up. All three blockers are addressed in Blocker 1 — fresh database can no longer be createdRemoved the partial index from Blocker 2 — unpause test contradicts the code
Blocker 3 — fail-closed discovery tests are vacuousRewrote the five fail-closed tests to capture the SQL Also added a concrete Non-blocking items — happy to address these in the same round or a follow-up. Let me know your preference. |
Closes #371
What changed
Added explicit provider enrollment state (provider_status enum: not_enrolled, pending_verification, active, suspended) so account creation, Red MicoPay membership, verification, and commercial availability are represented as independent facts.
Key changes
Tests
How to verify
cd micopay/backend npm install npm run test:discovery ALLOW_IN_MEMORY_DB=true MOCK_STELLAR=true SECRET_ENCRYPTION_KEY=0000000000000000000000000000000000000000000000000000000000000000 npm run test:abuseMigration
Run forward: DATABASE_URL=your_postgres npm run migrate
Run down: applies the down migration, schema returns to previous shape.
Not in scope