Skip to content

feat: add off-chain document reference handling for milestones#88

Open
Austinaminu2 wants to merge 1 commit intoDisciplr-Org:mainfrom
Austinaminu2:feature/off-chain-document-references
Open

feat: add off-chain document reference handling for milestones#88
Austinaminu2 wants to merge 1 commit intoDisciplr-Org:mainfrom
Austinaminu2:feature/off-chain-document-references

Conversation

@Austinaminu2
Copy link

Closes #19

What this PR does

Implements support for milestones that reference off-chain documents (URLs + optional content hashes stored in DB).

Files added

  • db/migrations/20260226000000_add_milestone_document_references.cjs — migration for milestone_document_references table
  • src/types/milestoneDocument.ts — TypeScript interfaces for document reference schema
  • src/services/milestoneDocumentValidator.ts — validation service for URLs and content hashes
  • src/routes/milestoneDocuments.ts — REST endpoints for creating and querying document references
  • src/services/milestoneDocumentValidator.test.ts — 24 unit tests

Files modified

  • src/index.ts — mounts /api/milestone-documents router
  • package.json — fixed pre-existing JSON syntax errors (duplicate keys, missing commas)
  • jest.config.ts — updated testMatch to cover src/**/*.test.ts

Schema

Table: milestone_document_references

  • id — primary key
  • vault_id — foreign key to vaults
  • label — human-readable name for the document
  • url — https URL to the off-chain document (max 2048 chars)
  • content_hash — optional hex-encoded hash for integrity verification
  • hash_algorithm — sha256 or sha512
  • created_at, updated_at

API endpoints

  • POST /api/milestone-documents — create a document reference
  • GET /api/milestone-documents?vaultId=<id> — list references for a vault
  • GET /api/milestone-documents/:id — get a single reference
  • DELETE /api/milestone-documents/:id — remove a reference

Secure URL handling strategy

  • Only https:// URLs are accepted — http, ftp, data URIs are all rejected
  • URL length is capped at 2048 characters
  • Domain allowlisting is supported via the ALLOWED_DOC_DOMAINS environment variable (comma-separated hostnames). Subdomains are also matched. If not set, any https domain is accepted.
  • URLs are never followed server-side — stored as references only, eliminating open redirect risk

Content hash validation

  • Hash and algorithm must be provided together or not at all
  • Supported algorithms: sha256 (64 hex chars), sha512 (128 hex chars)
  • Hash must be a valid hex string of the correct length for the algorithm

Tests

All 24 tests pass:

  • 9 URL validation tests (valid, empty, http, ftp, data URI, malformed, too long, allowlist, subdomain)
  • 8 content hash tests (valid sha256/sha512, missing fields, non-hex, wrong length, unsupported algorithm)
  • 7 full document validation tests (valid, with hash, missing fields, multiple errors)

@1nonlypiece
Copy link
Contributor

@can you resolve the conflicts?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Off-Chain Document Reference Handling

2 participants