-
Notifications
You must be signed in to change notification settings - Fork 0
feat: add comprehensive validation with detailed failure reasons #8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: add comprehensive validation with detailed failure reasons #8
Conversation
…lid_lexicons Renames all references to the validLexicons and invalidLexicons tables and types to valid_lexicons and invalid_lexicons for consistency with database naming conventions. Updates imports, queries, and type definitions across API routes and schema.
- Move InvalidLexiconReason and related reason interfaces to a new reasons.ts module - Move isZodError helper to types.ts for reuse - Simplify ValidationResult type and validation logic - Improve type safety and separation of concerns in validation code
… imports in schema
… updating Commit type - Remove unnecessary destructuring of commit object in ingest route - Use validationResult.lexiconDoc and commit.record directly for DB inserts and logging - Update Commit type to allow record to be any object, not just LexiconSchemaRecord - Minor import cleanup
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This pull request refactors the lexicon validation system to implement a flexible, extensible validator strategy pattern. The key change replaces the single validationErrors column with a typed reasons array that can store multiple types of validation failures with detailed error messages.
Key Changes:
- Implements a pluggable validator system with four validation types: NSID format, DID authority matching, rkey matching, and lexicon schema validation
- Replaces database
validation_errorsJSONB column with a strongly-typedreasonsJSONB array with CHECK constraint - Refactors table naming from camelCase to snake_case (validLexicons → valid_lexicons)
Reviewed changes
Copilot reviewed 14 out of 14 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| src/util/lexicon.ts | Removed - types moved to src/app/api/ingest/types.ts |
| src/db/schema.ts | Renamed tables to snake_case, replaced validationErrors with reasons array, added CHECK constraint and GIN index |
| src/app/api/stats/route.ts | Updated table references from camelCase to snake_case |
| src/app/api/repos/[repoDid]/route.ts | Updated table references from camelCase to snake_case |
| src/app/api/lexicons/route.ts | Updated table references from camelCase to snake_case |
| src/app/api/lexicons/resolve/route.ts | Updated table references from camelCase to snake_case |
| src/app/api/lexicons/[nsid]/route.ts | Updated table references from camelCase to snake_case |
| src/app/api/ingest/validation.ts | New file implementing validator strategy pattern with four validation types |
| src/app/api/ingest/types.ts | New file containing type definitions for commits, events, and type guards (moved from lexicon.ts) |
| src/app/api/ingest/route.ts | Refactored to use new validation system, simplified logic by delegating to validators |
| src/app/api/ingest/reasons.ts | New file defining typed validation failure reason interfaces |
| drizzle/meta/_journal.json | Updated migration timestamp (future date issue) |
| drizzle/meta/0000_snapshot.json | Updated schema snapshot with new table structure |
| drizzle/0000_init.sql | Updated initial migration SQL with new schema |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Parse the lexiconDoc from commit.record after all validations pass, instead of casting.
Summary
Replaces the single
validationErrorscolumn with a flexiblereasonsarray that supports multiple validation failure types. Implements a validator strategy pattern to collect all validation failures (NSID format, DID authority, rkey mismatch, schema errors) with detailed error messages for developer debugging.Key Changes
Database Schema
validation_errorscolumn withreasonsJSONB arrayreasonsarray is not emptyreasonsfor efficient queryingValidation Strategy Pattern
src/app/api/ingest/validation.tsFour Validation Types
@atproto/syntaxfor detailed error messagesType Safety
BaseCommitinterface for raw Nexus data (record: unknown)Commitinterface for validated data (record: LexiconSchemaRecord)isLexiconCommitfor proper TypeScript narrowingBenefits
Example Output
{ "reasons": [ { "type": "rkey_mismatch", "expected": "com.example.lexicon", "actual": "my-lexicon" }, { "type": "invalid_nsid_format", "nsid": "com.example_lexicon", "message": "Disallowed characters in NSID (ASCII letters, digits, dashes, periods only)" } ] }Breaking Changes
validation_errors→reasons(acceptable for pre-production)db:pushto apply migration