Repository navigation
docs: full documentation review; move SECURITY.md to .github/ - #56
Merged
Merged
Conversation
- Move SECURITY.md to .github/SECURITY.md (still detected by GitHub as the security policy) and update every reference to it. - Rewrite README.md against the current code: all 5 tools and 9 services, correct OAuth redirect URI (/api/auth/callback/ministryplatform), required MP_SECURITY_ROLES and the security env vars, setup wizard steps (Node 24), real Claude Code commands, dependency versions, project tree, MPHelper examples that follow the auth-gate and datetime rules, license status. - CLAUDE.md: full service list, Zod v4 note, schema import path, $userId example sourced from requireSecurityRole, vitest.config.mts, @types/node. - Verify and correct every .claude/references domain (auth, security, routing, mp-provider, mp-schema, services, data-flow, dto-constants, utils, components, contexts, testing) plus INDEX/GLOSSARY/DECISIONS/ GOTCHAS, commands and _meta; add services/family-service.md and a 2026-10-10 facts snapshot (118 files / 2,185 tests). - Fix stale comments (error.tsx, auth-wrapper.tsx, helper.ts JSDoc). - Open TODOs for code issues found during review: generated Zod schemas reject MP wall-clock datetimes, FieldManagementService Table_Name match, generator output paths, unused UserProvider, ungated GooglePlaces config read. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
…read (#57) ## Summary - `GooglePlacesService` now calls `AuthorizationService.requireSecurityRole({ table: "dp_Configuration_Settings", operation: "read" })` at the top of every public method (`isEnabled`, `autocomplete`, `getPlaceDetails`), on every call. The API key and provider are cached per process, so gating only the cache-miss path would have let an unauthorized caller use a key loaded by an authorized one. - The gate runs outside `resolveApiKey`'s try/catch, so a refusal throws `UnauthorizedError` instead of being swallowed into the env-var fallback. - Callers in `addeditfamily/actions.ts` are unchanged: they still gate `Addresses`/`read` first. `placeDetails` returns the error envelope and the others throw, the same as for their own gate. - Docs: removed GooglePlacesService from the ungated lists (services README, security README), noted the second gate in family-service.md, and refreshed error-catalog. Deleted TODO `2026-10-10-googleplaces-ungated-config-read.md`. INDEX.md is left for the lead. ## Test plan - [x] New tests: every method gates on `dp_Configuration_Settings`/`read`; a denied gate throws with no MP or Google call; a denied gate still throws when the key and provider are already cached (all 3 methods) - [x] `npm run lint`, `npm run typecheck`, `npx vitest run` (2192 passed) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
## Summary - `UserProvider` no longer calls `getCurrentUserProfile()` on mount. It fetches only after a component calls `useUser()`; that hook's effect calls an internal `requestProfile()` (private `UserProfileRequestContext`) which sets a `requested` flag. Repeat calls are a React bail-out, so all consumers share one load. - `useUser()` return shape (`userProfile`, `isLoading`, `error`, `refreshUserProfile`) unchanged; `userGuid`/`isPending` gating unchanged. - Hooks kept as a documented extension point: updated `contexts/README.md`, `contexts/user-provider.md`, `contexts/session.md`, ADR-015. Deleted the resolved TODO (`.claude/TODO/INDEX.md` left for the lead). ## Test plan - [x] New tests: no consumer → no call; two consumers → one call; late-mounting consumer triggers exactly one call - [x] Existing 11 user-context tests still pass - [x] `npm run lint`, `npm run typecheck`, `npx vitest run --coverage` (2188 tests, thresholds met) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…llback (#59) ## Summary - One read-only live `GET /tables?$search=Contacts` showed each entry's keys are exactly `Name`, `AccessLevel`, `SpecialPermissions`, `Columns`. There is no `Table_ID`, `Table_Name` or `Display_Name`. - `FieldManagementService.getTableMetadata` matched on `t.Table_Name`, which never hit, so it always fell back to `tables[0]`. - `TableMetadata` now has `Name` + `Columns` + an index signature. `getTableMetadata` does an exact, case-sensitive `Name` match and returns `null` on a miss. `fetchPageFieldData` already handles `null`: it merges no columns. - Tests added: the exact match is not the first result; no exact match returns null; a legacy `Table_Name` key is ignored; matching is case-sensitive. Fixtures switched to `Name`. - Docs updated: `field-management-service.md`, `mp-provider/services/metadata.md`, GOTCHA-017. Deleted the TODO. ## Test plan - [x] `npm run lint` - [x] `npm run typecheck` - [x] `npx vitest run`: 2187/2187 passed 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…te catalogs to mp-schema/ (#60) ## Summary Fixes two TODOs: `2026-10-10-generated-zod-rejects-mp-datetimes` and `2026-10-10-generators-write-old-doc-paths` (both deleted; `.claude/TODO/INDEX.md` left for the lead). **Zod datetimes** - `mapDataTypeToZod` now emits, inline, `z.string().regex(/^\d{4}-\d{2}-\d{2}[ T]\d{2}:\d{2}(:\d{2}(\.\d+)?)?(Z|[+-]\d{2}:?\d{2})?$/, …)` for `DateTime`/`Timestamp` instead of `z.string().datetime()`. It accepts MP wall-clock (`toMpSqlDatetime` output) and ISO forms. - `Date` columns use the same shape with the time part optional (MP returns them as `YYYY-MM-DDT00:00:00`, which `z.string().date()` rejected). - Removed the temporary "known conflict" caveats from CLAUDE.md, README, the `helper.ts` JSDoc and the reference docs. The README/helper examples pass `schema: ContactLogSchema` again. **Generator outputs** - `generate-types.ts` writes `.claude/references/mp-schema/tables.md` and `generate-storedprocs.ts` writes `.claude/references/mp-schema/stored-procs.md`, both with their frontmatter (`last_verified` = generation date). - A `--search` run can't overwrite either catalog: types skips `tables.md`, and storedprocs requires `-o` with `-s`. - `models/index.ts` is built by scanning the output directory, so `--search` no longer drops the other tables from the barrel. - Dropped the `TableMetadataWithName` / `Name ?? Table_Name` workaround and now use `table.Name`, following #59. **Live regeneration** (`mp:generate:models` + `mp:generate:storedprocs`) - Tables went from 301 to 307: 10 added (e.g. `_Deployment_Logs`, `dp_Charts`, `dp_Communication_Messages_Archived`, `Wait_Stats_*`) and 4 removed (`vw_mp_Giving_Unit_Summary` replaced by `…_Standard`, `Z_*_Notifications`). - A few columns changed (e.g. `Congregations.Vanco_Signing_Key` removed). - Stored procs went from 532 to 539. - No app code referenced anything that was removed. ## Test plan - [x] New `generate-types.test.ts` / `generate-storedprocs.test.ts` cover: accepted and rejected datetime/date strings (checked against real Zod), the generated schema module, the barrel scan, and catalog frontmatter - [x] `npm run lint` - [x] `npm run typecheck` (passes against the regenerated models) - [x] `npx vitest run`: 120 files, 2237 tests passing 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
All five TODOs opened in the doc review were fixed in #57-#60; clear them from .claude/TODO/INDEX.md (0 open). Point DECISIONS ADR-012 and the setup wizard message at the new mp-schema/ catalog paths, and refresh the test inventory (120 files / 2,237 cases) after the new generator, gate and lazy-fetch tests. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
SECURITY.md→.github/SECURITY.md(still detected by GitHub as the security policy) and updates every reference.README.mdagainst the current code. Fixes the documented OAuth redirect URI (/api/auth/callback/ministryplatform; the old/oauth2/callback/...path is blocked by the route allowlist). Adds the requiredMP_SECURITY_ROLESand the security env vars, all 5 tools / 9 services, the real setup wizard steps (Node 24), the 4 existing Claude Code commands, current dependency versions, and examples that follow the auth-gate and datetime rules.CLAUDE.md: theCongregationsandContactLogSchemaimports didn't compile, and the$userIdexample contradicted rule 13. Also completes the service list and corrects stale versions and file names..claude/referencesdomain plus INDEX/GLOSSARY/DECISIONS/GOTCHAS, commands and_meta. Addsservices/family-service.mdand a 2026-10-10 facts snapshot.toolService.test.ts:error.tsx,auth-wrapper.tsx,helper.tsJSDoc.Code fixes merged into this branch (found during the review)
GooglePlacesServicegated ondp_Configuration_Settings/read on every public method (a cached API key can't be used without the role).UserProviderfetches the profile lazily on the firstuseUser()call (no MP call per page load with no consumer).FieldManagementService.getTableMetadatamatches onName(confirmed with a live read-only call: the API never returnsTable_Name); notables[0]fallback.TableMetadatatype corrected.mp-schema/; the--searchrun no longer clobbers the barrel or catalog. Models regenerated from live MP (301 → 307 tables, 532 → 539 procs).All TODOs closed (0 open).
Open question
The repo is public with no LICENSE file. The README now says so; previously it said "Private".
Test plan
npm run lintnpm run typechecknpx vitest run: 120 files / 2,237 tests pass🤖 Generated with Claude Code