You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: context/progress-tracker.md
+8-113Lines changed: 8 additions & 113 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -27,6 +27,14 @@ pure chore/docs commits). Direct pushes to main must also be logged here.
27
27
event, blocked-user denial within TTL bound, cache expiry re-query,
28
28
cleanup job deletes-only-expired.
29
29
30
+
## 2026-08-26
31
+
32
+
- Fixed registration race conditions in `AuthService.register()` by eliminating application-side pre-checks (`findByWallet`, `checkUsernameExists`) and relying directly on DB-level UNIQUE constraints (`users.wallet_address`, `users.username`).
33
+
- Added idempotent migration `20260826130000_ensure_users_unique_constraints.sql` to ensure unique indexes exist on `users.wallet_address` and `users.username`.
34
+
- Updated `UsersRepository.createProfile()` to catch PostgreSQL unique constraint violation error `23505` and map to structured 409 `ConflictException` (`AUTH_WALLET_EXISTS`, `AUTH_USERNAME_TAKEN`).
35
+
- Added cleanup handlers (`deleteAvatar`, `deleteUserById`) in `AuthService.register()` and `UsersRepository` to ensure failed registrations do not leave orphaned avatar files or partial user records.
36
+
- Added unit tests covering DB unique constraint error mapping, parallel race conditions for duplicate wallet and username registrations, sequential re-registration compatibility, and avatar/user cleanup on failure.
37
+
30
38
## 2026-07-23
31
39
32
40
- Added GitHub Actions health check workflow (`health-check.yml`) to ping the Render API every 6 hours to prevent the free tier instance from sleeping. Auto-creates or comments on issues with the `incident` label if the ping fails, preventing silent outages.
@@ -117,120 +125,7 @@ pure chore/docs commits). Direct pushes to main must also be logged here.
117
125
118
126
---
119
127
120
-
<<<<<<< Updated upstream
121
128
> Note (2026-07-16): this file previously contained StepFi-Contracts
122
129
> content copied from the wrong repo. Replaced with real StepFi-API
123
130
> history backfilled from `git log`. Entries older than 2026-06-18 are
124
131
> in git history but were never tracked here.
125
-
=======
126
-
## Completed
127
-
128
-
### Workspace Cleanup
129
-
- Removed dead code: `lp-contract` (superseded by `liquidity-pool-contract`)
-`node_modules` cached via `actions/cache@v4` keyed on `package-lock.json` hash
160
-
- CI status badge added to `README.md` pointing at the workflow
161
-
162
-
### Vendor Approval Lifecycle
163
-
- Created database migration `20260817000001_add_vendor_status.sql` adding `status` column constrained to `pending`, `approved`, `suspended`, `rejected`, defaulting to `pending` and backfilling existing rows.
164
-
- Added `buildApproveVendorXdr` and `buildSuspendVendorXdr` methods to `VendorRegistryContractClient` and `IVendorRegistryClient` to construct unsigned Soroban transaction XDRs.
165
-
- Created `AdminGuard` to enforce allowlisted wallet access via `ADMIN_WALLETS` (401 for unauthenticated, 403 for non-admin).
166
-
- Created `AuditAction` decorator and `AuditInterceptor` for audit-logging privileged admin operations.
167
-
- Added `POST /vendors/:id/approve` and `POST /vendors/:id/suspend` endpoints returning unsigned XDRs, guarded with `JwtAuthGuard` and `AdminGuard`, decorated with full Swagger annotations and returning HTTP 409 Conflict for invalid vendor status transitions (`VENDOR_NOT_PENDING`, `VENDOR_NOT_APPROVED`).
168
-
- Integrated status updates into `TransactionStatusCheckerProcessor` to update local Supabase `vendors` status only after on-chain transaction confirmation.
169
-
### Learner Profile Auto-Creation
170
-
- Added automatic creation of `learner_profiles` records upon first sign-in in `AuthService.findOrCreateUser()`, ensuring `GET /learners/me` resolves immediately after authentication.
171
-
- Updated `auth.service.spec.ts` unit tests to cover table query and insertion handling for `learner_profiles`.
172
-
173
-
174
-
---
175
-
176
-
## In Progress
177
-
178
-
- None currently.
179
-
180
-
---
181
-
182
-
## Next Up (In Order)
183
-
184
-
1.**LoanType enum** — Add `LoanType::LearnerInstallment` variant to `creditline-contract/src/types.rs`
185
-
2.**Per-installment tracking** — Add `paid: bool` and `paid_at: u64` fields to `RepaymentInstallment` struct
186
-
3.**repay_installment()** — New function targeting a specific installment by index (instead of just reducing remaining balance)
187
-
4.**Learner grace period** — Make `grace_period_seconds` per-loan (not just global via parameters)
188
-
5.**Vouching contract** — New `vouching-contract` crate: `vouch()`, `revoke_vouch()`, `get_vouches()`, `get_vouch_count()`
189
-
6.**Reputation rules** — Update `creditline-contract` to call different reputation adjustments for `LoanType::LearnerInstallment`
190
-
7.**Testnet deployment** — Deploy all contracts, capture IDs, add to StepFi-API `.env`
191
-
8.**End-to-end validation** — Verify loan lifecycle on testnet via Stellar CLI
192
-
193
-
---
194
-
195
-
## Open Questions
196
-
197
-
- What token is used for loans — native XLM or a USDC anchor? (Affects token contract address in `initialize()`)
198
-
- Should the vouching contract be a standalone crate or logic added to `creditline-contract`? (Leaning toward standalone for modularity)
199
-
- What is the correct `grace_period_seconds` for learner installment loans? (Longer than standard BNPL — possibly 7-14 days per installment)
200
-
- Should sponsor pool deposits go through `liquidity-pool-contract` or a new `sponsor-pool-contract`?
201
-
202
-
---
203
-
204
-
## Architecture Decisions
205
-
206
-
-**5 contracts, not 6** — `lp-contract` was dead code, removed. `liquidity-pool-contract` is the canonical LP implementation.
207
-
-**Vendor over Merchant** — Renamed to reflect StepFi's learning-focused domain.
208
-
-**TTL approach** — Using 60-day threshold / 120-day extension constants. Off-chain indexer is responsible for bumping TTL on active loan entries.
209
-
-**Upgrade pattern** — All contracts have `upgrade()` gated by admin `require_auth()`. Admin address is set at `initialize()` and transferable via `set_admin()`.
210
-
-**Loan sharding** — 32 shards (`loan_id % 32`) in creditline-contract to distribute persistent storage keys and avoid hot-key contention.
211
-
-**Reentrancy** — Boolean `LOCKED` flag in instance storage. Cheaper than mutex, sufficient for Soroban's single-threaded execution model.
212
-
213
-
---
214
-
215
-
## Contract Deployment Status
216
-
217
-
| Contract | Testnet Deployed | Contract ID | Last Deployed |
218
-
|---|---|---|---|
219
-
|`reputation-contract`| ❌ No | — | — |
220
-
|`parameters-contract`| ❌ No | — | — |
221
-
|`vendor-registry-contract`| ❌ No | — | — |
222
-
|`liquidity-pool-contract`| ❌ No | — | — |
223
-
|`creditline-contract`| ❌ No | — | — |
224
-
225
-
> Update this table after running `scripts/deploy-testnet.sh`
226
-
227
-
---
228
-
229
-
## Session Notes
230
-
231
-
- Always run `cargo build` after any contract change before committing.
232
-
- Always run `cargo test` before marking any contract feature complete.
233
-
- Never modify storage key structures of a contract that has been deployed — it breaks existing data. Use a migration pattern or deploy a new contract.
234
-
- The `creditline-contract` depends on all other contracts — it must be initialized last.
235
-
- Do not add new workspace members to `Cargo.toml` without creating the full contract file structure first.
0 commit comments