Runbook: Riff #165 — admin-console workspace dep + POC migration¶
Status: ready to execute. Operator-gated on sudo chown.
Tracks: Riff #165.
Effort: ~10 min operator + ~10 min for the code patch + verify.
Prerequisite: admin-console node_modules is root-owned (legacy Docker mount). npm install fails with "operation rejected by your operating system."
Why¶
Plan #026 Slice J shipped the generated-client-type POC in partner-console (payment.service.ts uses satisfies keyof PaymentPaths for typed URL templates). The admin-console half stayed deferred because we couldn't npm install @po/contracts over root-owned node_modules.
This runbook unblocks it.
Steps¶
1. Fix the directory ownership (one command)¶
sudo chown -R "$USER:$USER" frontends/admin-console/node_modules
# OR — if you'd rather wipe + reinstall (safer if the existing tree
# has half-installed bits from past docker volume mounts):
sudo rm -rf frontends/admin-console/node_modules
2. Wire the workspace dep into admin-console¶
Edit frontends/admin-console/package.json — add the entry in dependencies (alphabetical):
"dependencies": {
"@hookform/resolvers": "^5.2.2",
+ "@po/contracts": "file:../../packages/contracts",
"@radix-ui/react-collapsible": "^1.1.12",
3. Reinstall¶
This regenerates package-lock.json to include @po/contracts. Both files (package.json + lockfile) get committed.
4. Apply the POC migration to payment.service.ts¶
The pattern is identical to frontends/partner-console/src/services/payment.service.ts:
import { getPaymentServiceUrl } from '@/utils/domain-detector';
import { apiClient } from '@/utils/api-client';
+import type { paths as PaymentPaths } from '@po/contracts/clients/payment-service/types';
const API_BASE = getPaymentServiceUrl();
+
+/**
+ * Plan #026 Slice J — generated-spec consumption POC (admin-console half).
+ *
+ * URL constants are typed against the generated `PaymentPaths` keys, so
+ * any rename / deletion of the upstream route fails `tsc --noEmit` at
+ * build time. `keyof PaymentPaths` is the source of truth.
+ */
+const REFUNDS_LIST_PATH =
+ '/payments/refunds' satisfies keyof PaymentPaths;
+const REFUND_BY_ID_PATH =
+ '/payments/refunds/{id}' satisfies keyof PaymentPaths;
+const TRANSFERS_LIST_PATH =
+ '/payments/transfers' satisfies keyof PaymentPaths;
+const TRANSFER_REVERSAL_PATH =
+ '/payments/transfers/{id}/reversal' satisfies keyof PaymentPaths;
+const DISPUTES_LIST_PATH =
+ '/payments/disputes' satisfies keyof PaymentPaths;
+const DISPUTE_BY_ID_PATH =
+ '/payments/disputes/{id}' satisfies keyof PaymentPaths;
Then update each URL builder in the service object:
- const url = `${API_BASE}/payments/refunds${buildQuery(filters)}`;
+ const url = `${API_BASE}${REFUNDS_LIST_PATH}${buildQuery(filters)}`;
Repeat for the 7 URL constructions (listRefunds, getRefund, createRefund, listTransfers, reverseTransfer, listDisputes, getDispute) — see frontends/admin-console/src/services/payment.service.ts:174-252 for current literals.
5. Extend the test¶
In frontends/admin-console/src/pages/PaymentsPage.test.tsx (or wherever the smoke covering the service lives), add the type-safety assertion:
import type { paths as PaymentPaths } from '@po/contracts/clients/payment-service/types';
describe('payment.service URL constants', () => {
it('all template paths satisfy keyof PaymentPaths', () => {
// Compile-time guard — if any literal drifts from the generated spec,
// tsc fails at this assertion. The runtime assertion is a smoke check.
const _refunds: keyof PaymentPaths = '/payments/refunds';
const _transfers: keyof PaymentPaths = '/payments/transfers';
const _disputes: keyof PaymentPaths = '/payments/disputes';
expect(_refunds).toBe('/payments/refunds');
expect(_transfers).toBe('/payments/transfers');
expect(_disputes).toBe('/payments/disputes');
});
});
6. Verify¶
cd frontends/admin-console
npx tsc --noEmit # must be clean
npm run lint # must be clean
npm test # PaymentsPage suite + new assertion green
7. Commit + push¶
cd ../..
git add frontends/admin-console/package.json \
frontends/admin-console/package-lock.json \
frontends/admin-console/src/services/payment.service.ts \
frontends/admin-console/src/pages/PaymentsPage.test.tsx
git commit -m "[sA] chore(admin-console): Riff #165 — @po/contracts workspace dep + payment.service POC
Closes Plan #026 Slice J's deferred admin-console half. Same pattern
as partner-console payment.service.ts (commit 55c6e4f): URL constants
typed against generated PaymentPaths, so any upstream route rename
fails tsc at build time."
git push
8. Flip Riff #165 → done¶
After the pipeline goes green.
Rollback¶
If npm install errors after sudo chown, the chown can be reverted:
But there's no reason to — node_modules should never be root-owned on a dev laptop. The chown is the right state.
Cross-references¶
- Riff
#165: tasks-prod - Plan #026 retrospective:
docs/implementation-plans/026-test-foundation-structural-hygiene/RETROSPECTIVE.md - partner-console POC reference:
frontends/partner-console/src/services/payment.service.ts(commit55c6e4f) - OpenAPI gate doc:
docs/developers/api/openapi.md