Skip to content

Feat/fixing migrations - #178

Merged
leboiko merged 16 commits into
v2_0from
feat/fixing-migrations
Jan 12, 2026
Merged

leboiko merged 16 commits into
v2_0from
feat/fixing-migrations

Conversation

@leboiko

@leboiko leboiko commented Dec 1, 2025

Copy link
Copy Markdown
Member

No description provided.

@claude

claude Bot commented Dec 1, 2025

Copy link
Copy Markdown

Pull Request Review: Feat/fixing migrations (PR #178)

Summary

This PR includes substantial improvements to the database migration system, comprehensive architecture documentation, and critical fixes for position count accuracy issues. The changes span 17 files with 2,385 additions and 28 deletions.


📋 Changes Overview

1. Documentation (New Files) ✅

  • ARCHITECTURE_PROPOSAL.md (472 lines): Production-ready event sourcing architecture spec
  • SYSTEM_ARCHITECTURE_CURRENT.md (731 lines): Current system architecture documentation
  • RELEVANCE_SCORING_FORMULA.md (37 lines): Search ranking algorithm specification
  • docs/README.md (83 lines): Documentation index and navigation guide

2. Database Migrations 🔧

  • Consolidated triggers migration: Refactored trigger functions with retry logic
  • Position count fix functions: Three new utility functions for data integrity maintenance

3. Scripts & Tooling 📝

  • Position count verification and fix utilities
  • Comprehensive analysis documentation

4. Hasura Metadata Updates

  • Updated relationship mappings for 5 tables (atom, atom_value, term, triple, triple_term)

🎯 Strengths

Documentation Quality ⭐

The new documentation is exceptional:

  • Comprehensive system architecture with clear diagrams (Mermaid)
  • Production-ready specifications with concrete implementation guidance
  • Well-organized with a helpful README index
  • Addresses real-world scale concerns (300k vaults, 4M+ positions)

Database Trigger Improvements ✅

The consolidated trigger migration shows solid improvements:

Before:

UPDATE vault
SET position_count = position_count + 1
WHERE term_id = NEW.term_id AND curve_id = NEW.curve_id;

After (infrastructure/hasura/migrations/intuition/1729947331635_consolidated_triggers/up.sql:315-348):

DECLARE
    affected_rows INTEGER;
    retry_count INTEGER := 0;
    max_retries INTEGER := 3;
BEGIN
  IF NEW.shares > 0 THEN
    LOOP
      UPDATE vault
      SET position_count = position_count + 1
      WHERE term_id = NEW.term_id AND curve_id = NEW.curve_id;
      
      GET DIAGNOSTICS affected_rows = ROW_COUNT;
      
      IF affected_rows > 0 OR retry_count >= max_retries THEN
        EXIT;
      END IF;
      
      PERFORM pg_sleep(0.01);
      retry_count := retry_count + 1;
    END LOOP;

This adds:

  • ✅ Retry logic for race conditions
  • ✅ Warning logs for failures
  • ✅ Graceful degradation

Position Count Fix Functions 🛠️

Three well-designed utility functions (infrastructure/hasura/migrations/intuition/1729947331638_fix_position_count_functions/up.sql):

  1. fix_all_position_counts(): Full recalculation
  2. fix_wrong_position_counts(): Selective fix (more efficient)
  3. fix_position_counts_for_term(): Targeted fix for specific term_id

These provide excellent operational tooling with proper down migration support.


⚠️ Issues & Concerns

1. CRITICAL: Missing Rollback Strategy

The consolidated triggers migration lacks a proper down migration. The file references:

infrastructure/hasura/migrations/intuition/1729947331635_consolidated_triggers/down.sql

This file is NOT in the PR. Without it:

  • ❌ Cannot rollback if issues arise in production
  • ❌ Violates migration best practices
  • ❌ Could block future migration rollbacks

Recommendation: Add a down.sql that:

-- Drop retry-enabled functions
DROP FUNCTION IF EXISTS increment_vault_position_count() CASCADE;
DROP FUNCTION IF EXISTS reopen_vault_position_count() CASCADE;
-- ... etc

-- Restore original simple functions
CREATE OR REPLACE FUNCTION increment_vault_position_count() ...

2. SECURITY: Trigger Functions Use pg_sleep()

Location: infrastructure/hasura/migrations/intuition/1729947331635_consolidated_triggers/up.sql:336

PERFORM pg_sleep(0.01);  -- 10ms sleep in trigger

Concerns:

  • 🚨 Can cause transaction buildup under high load
  • 🚨 May lead to lock escalation and deadlocks
  • 🚨 3 retries × 10ms = 30ms worst-case per position update

During 300+ EPS (per ARCHITECTURE_PROPOSAL.md), this could cause:

  • Connection pool exhaustion
  • Cascading failures
  • Database performance degradation

Alternative Solutions:

  1. Advisory Locks: Use pg_try_advisory_xact_lock() for coordination
  2. Optimistic Concurrency: Accept some drift, fix periodically with fix_wrong_position_counts()
  3. Queue-based Updates: Batch position count updates asynchronously

Recommendation:

  • Remove retry logic from triggers OR
  • Document maximum concurrent load testing results OR
  • Implement advisory locks instead of sleeps

3. RACE CONDITION: Vault Creation Timing

The architecture docs acknowledge that vaults are created by SharePriceChanged events (docs/SYSTEM_ARCHITECTURE_CURRENT.md:106-107), but the trigger functions don't handle vault-not-yet-exists cases.

In consolidated_triggers/up.sql:322-326:

UPDATE vault
SET position_count = position_count + 1
WHERE term_id = NEW.term_id AND curve_id = NEW.curve_id;

Problem: If a Deposited event is processed before the corresponding SharePriceChanged event creates the vault:

  • The UPDATE affects 0 rows
  • affected_rows = 0 triggers retry loop
  • After 3 retries × 10ms, warning is logged but position count is wrong

Evidence from analysis: scripts/position-count-analysis.md:26-28 shows 452 vaults with wrong counts, many off by 1.

Recommendation:

  • Add existence check: IF NOT EXISTS (SELECT 1 FROM vault WHERE ...) THEN RETURN NEW; END IF;
  • Or: Create vault record in trigger if missing (with default values)
  • Or: Document that fix_wrong_position_counts() should run after each indexing batch

4. PERFORMANCE: Inefficient Subqueries in Aggregate Updates

infrastructure/hasura/migrations/intuition/1729947331635_consolidated_triggers/up.sql:184-190

UPDATE triple_term
SET 
    total_assets = COALESCE((SELECT SUM(total_assets) FROM vault WHERE term_id IN (term_id_val, counter_term_id_val)), 0),
    total_market_cap = COALESCE((SELECT SUM(market_cap) FROM vault WHERE term_id IN (term_id_val, counter_term_id_val)), 0),
    total_position_count = COALESCE((
        SELECT SUM(v.position_count) 
        FROM vault v 
        WHERE v.term_id IN (term_id_val, counter_term_id_val)
    ), 0),

Issues:

  • 🐌 Three separate subqueries scanning the same vault rows
  • 🐌 No indexes on vault.term_id mentioned in PR (needs verification)

Recommendation: Use single CTE:

WITH vault_aggs AS (
    SELECT 
        SUM(total_assets) as sum_assets,
        SUM(market_cap) as sum_cap,
        SUM(position_count) as sum_count
    FROM vault 
    WHERE term_id IN (term_id_val, counter_term_id_val)
)
UPDATE triple_term
SET 
    total_assets = COALESCE((SELECT sum_assets FROM vault_aggs), 0),
    total_market_cap = COALESCE((SELECT sum_cap FROM vault_aggs), 0),
    total_position_count = COALESCE((SELECT sum_count FROM vault_aggs), 0)
...

5. CODE QUALITY: Inconsistent Error Handling

Some functions return after logging warnings (consolidated_triggers/up.sql:341-344):

IF affected_rows = 0 THEN
    RAISE WARNING '...';
END IF;

But others use RETURN NULL (consolidated_triggers/up.sql:155):

RETURN NULL;

Issue: Triggers that RETURN NULL prevent further triggers from firing on the same row.

Recommendation:

  • Always return NEW for AFTER INSERT/UPDATE triggers
  • Return OLD for AFTER DELETE triggers
  • Document why some triggers intentionally return NULL

6. TEST COVERAGE: No Tests for New Functions

The PR adds:

  • 3 new position count fix functions
  • 4 modified trigger functions with retry logic
  • Multiple aggregate update triggers

Missing:

  • ❌ No unit tests for fix functions
  • ❌ No integration tests for race conditions
  • ❌ No load tests for high-concurrency scenarios
  • ❌ No verification that retries actually resolve issues

Recommendation:
Add tests in integration-tests/:

-- Test 1: Verify fix_wrong_position_counts() accuracy
-- Test 2: Concurrent position updates don't cause drift
-- Test 3: Retry logic handles temporary vault absence
-- Test 4: Performance under 300+ EPS load

7. DOCUMENTATION: Migration Order Dependency

The consolidated triggers migration (1729947331635) must run BEFORE the position count fix migration (1729947331638), but this dependency is not documented.

Recommendation: Add comment in migration header:

-- IMPORTANT: This migration must run AFTER 1729947331635_consolidated_triggers
-- as it depends on the updated trigger functions

🔍 Detailed Code Review

Hasura Metadata Changes (Minor)

The YAML changes look good - they're mostly adding relationship mappings:

  • ✅ public_atom.yaml: Added cached_image remote relationship
  • ✅ public_triple.yaml: Added counter_positions array relationship
  • ✅ Consistent formatting and structure

No issues detected in metadata changes.

Scripts & Documentation

scripts/POSITION_COUNT_FIX_FUNCTIONS.md: Excellent operational documentation

  • Clear usage examples with actual output
  • Proper authentication guidance
  • Troubleshooting section
  • Best practices

scripts/position-count-analysis.md: Good analysis showing:

  • 452 vault mismatches (-452 total)
  • 244 triple_term mismatches (7,495 total difference)
  • Root cause hypotheses

scripts/fix-position-counts.sql: Clean one-time fix script with transaction wrapping.

.gitignore Change ✅

+scripts/backups/*

Simple and appropriate for excluding backup files.


🔒 Security Considerations

1. SQL Injection: ✅ SAFE

All functions use parameterized queries or proper DECLARE'd variables. No string concatenation for SQL construction.

2. Privilege Escalation: ✅ SAFE

Functions use SECURITY DEFINER implicitly but don't expose dangerous operations.

3. DoS Risk: ⚠️ MODERATE

The pg_sleep() in triggers could be exploited:

  • Attacker creates many concurrent deposits
  • Each triggers 3 × 10ms sleeps
  • Database connections exhausted

Recommendation: Add connection pool monitoring and rate limiting.


📊 Performance Analysis

Estimated Impact (based on ARCHITECTURE_PROPOSAL.md scale)

Scenario: 300 deposits/second, 10% trigger vault updates

Without this PR:

  • 30 vault updates/sec × 1ms = 30ms/sec total

With this PR (worst case):

  • 30 vault updates/sec × 30ms (3 retries) = 900ms/sec total
  • 30x performance degradation risk

With this PR (best case):

  • 30 vault updates/sec × 1ms (no retries) = 30ms/sec total
  • No change

Recommendation:

  • Load test with production-like concurrency
  • Monitor affected_rows = 0 warning frequency
  • Consider removing retries if warnings are rare (use scheduled fixes instead)

✅ Recommendations Summary

High Priority (Must Fix Before Merge)

  1. Add down.sql migration for consolidated_triggers
  2. Remove pg_sleep() retries or prove safety with load tests
  3. Handle vault-not-exists case in position count triggers
  4. Add CTE optimization to aggregate update functions

Medium Priority (Should Fix)

  1. Add integration tests for concurrent scenarios
  2. Document migration order dependencies
  3. Standardize trigger return values (NEW vs NULL vs OLD)

Low Priority (Nice to Have)

  1. Add performance benchmarks to PR description
  2. Create runbook for using fix functions in production
  3. Add monitoring alerts for position count drift

🎯 Verdict

Overall Assessment: ⚠️ APPROVE WITH CONDITIONS

This PR makes significant positive contributions:

  • ✅ Excellent documentation
  • ✅ Addresses real data integrity issues
  • ✅ Provides operational tooling
  • ✅ Improved trigger resilience

However, it introduces performance and reliability risks:

  • ⚠️ pg_sleep() in hot path
  • ⚠️ Missing rollback migration
  • ⚠️ Race condition handling incomplete
  • ⚠️ No test coverage

Recommended Merge Strategy:

Option A (Conservative):

  1. Merge documentation only (safe)
  2. Address critical issues in follow-up PR
  3. Load test trigger changes
  4. Merge migrations after validation

Option B (Aggressive):

  1. Add down.sql migration
  2. Document that fix_wrong_position_counts() should run hourly
  3. Merge with monitoring plan
  4. Rollback if issues arise in first 24h

🙏 Acknowledgments

This is a substantial and well-thought-out PR. The documentation quality is outstanding, and the position count fix functions are production-ready. The retry logic in triggers shows good defensive programming instincts. With the recommended fixes, this will be a solid improvement to the system.

Great work on the comprehensive architecture documentation - it will be invaluable for future development! 🎉


Generated by Claude Code 🤖

@claude

claude Bot commented Dec 1, 2025

Copy link
Copy Markdown

Pull Request Review: Feat/fixing migrations

Summary

This PR converts Hasura relationship definitions from using foreign_key_constraint_on to manual_configuration across 4 table metadata files. This is a significant metadata restructuring change that affects the GraphQL API's relationship handling.

Code Quality & Best Practices ✅

Strengths:

  • Consistent Pattern: All changes follow the same conversion pattern from foreign_key_constraint_on to manual_configuration
  • Explicit Column Mapping: The manual configuration makes relationships more explicit with clear column mappings
  • Proper Structure: All manual configurations include the required fields: column_mapping, insertion_order, and remote_table

Observations:

  • The conversion from automatic foreign key tracking to manual configuration is systematic across all 4 files
  • Currently 39 relationships in the codebase still use foreign_key_constraint_on vs 83 using manual_configuration - this PR moves toward consistency

Files Changed

1. public_atom.yaml (19 additions, 5 deletions)

  • ✅ Converted 3 object relationships: creator, term, and value
  • All use proper column mappings (creator_id→id, term_id→id, value_id→id)

2. public_atom_value.yaml (21 additions, 3 deletions)

  • ✅ Converted 3 object relationships: account, atom, and caip10
  • Note: The atom relationship has an unusual mapping: id→term_id (reverse direction)

3. public_term.yaml (15 additions, 9 deletions)

  • ✅ Converted 3 relationships: tripleById, positions, and vaults
  • Changed from array relationship pattern to manual configuration

4. public_triple_term.yaml (14 additions, 2 deletions)

  • ✅ Converted 2 object relationships: counter_term and term
  • Both map to the same term table with different column mappings

Potential Issues & Concerns ⚠️

1. Reverse Relationship Mapping (Medium Priority)

In public_atom_value.yaml:22-24, the atom relationship maps:

column_mapping:
  id: term_id

This appears to be a reverse foreign key where atom_value.id references atom.term_id. This is unusual and should be verified:

  • Is this intentional?
  • Does atom.term_id actually reference atom_value.id?
  • This may indicate a bidirectional relationship that needs clarification

2. Missing Foreign Key Constraints in Database (High Priority)

Converting to manual_configuration suggests that:

  • Either the database foreign key constraints don't exist
  • Or Hasura can't detect them automatically

Recommendation: Verify that proper database-level foreign key constraints exist. If they're missing, consider adding them for data integrity, even if using manual configuration in Hasura.

3. Migration Impact (High Priority)

This PR title mentions "fixing migrations" but:

  • No actual database migration files are included
  • Only Hasura metadata is changed
  • This suggests the database schema already exists and this is correcting the metadata

Questions to consider:

  • Are there corresponding database migrations that should accompany this?
  • Was the previous configuration failing/broken?
  • What issue prompted this change?

4. Consistency Across Codebase (Medium Priority)

Based on the grep results:

  • 39 relationships still use foreign_key_constraint_on
  • 83 relationships use manual_configuration

Recommendation: Consider documenting the strategy:

  • Should all relationships be converted to manual configuration?
  • Are there specific cases where foreign_key_constraint_on is preferred?
  • A follow-up PR to standardize the remaining relationships might be beneficial

Security Considerations 🔒

✅ No Direct Security Concerns

  • These are metadata definitions only
  • The select_permissions sections remain unchanged
  • No changes to authentication or authorization logic
  • No SQL injection risks as this is declarative configuration

Performance Considerations ⚡

Neutral Impact

  • Manual vs automatic relationship tracking should have minimal performance difference
  • Both approaches result in the same GraphQL queries and database joins
  • No indexing or query structure changes

Test Coverage 🧪

Concerns:

  • ❌ No test files included in this PR
  • ❌ No evidence of testing the GraphQL API after these changes
  • ❌ No migration rollback test

Recommendations:

  1. Test all affected GraphQL queries to ensure relationships still resolve correctly
  2. Verify both forward and reverse relationship traversals work
  3. Test with the integration test suite (especially src/vaults.test.ts and related files)
  4. Consider adding automated tests for metadata validation

Action Items

Before Merging:

  1. Clarify the purpose: Add a description to the PR explaining what issue this fixes
  2. Verify the atom_value.atom relationship: Confirm the id→term_id mapping is correct
  3. Test GraphQL queries: Ensure all relationships work as expected:
    query TestRelationships {
      atom { creator { id } term { id } value { id } }
      atom_value { account { id } atom { id } caip10 { id } }
      term { positions { id } vaults { id } }
      triple_term { counter_term { id } term { id } }
    }
  4. Document the change: Update any relevant documentation about the metadata structure

Future Considerations:

  1. Standardize remaining relationships: Plan to convert or document why the remaining 39 foreign_key_constraint_on relationships should stay
  2. Add metadata validation tests: Automated checks for relationship integrity
  3. Database constraints audit: Ensure all implied foreign keys exist at the database level

Overall Assessment

Status: ⚠️ Approve with Recommendations

This PR makes systematic, consistent changes to Hasura metadata configuration. The code quality is good and follows a clear pattern. However, the lack of context (PR description, associated migrations, test evidence) and the unusual reverse relationship in atom_value warrant clarification before merging.

The changes themselves appear technically sound, but without understanding the problem being solved, it's difficult to fully validate the solution.

Suggested PR Description Template:

## Problem
[Describe what was broken/why this change is needed]

## Solution
Converted relationship definitions from foreign_key_constraint_on to manual_configuration for:
- public_atom
- public_atom_value  
- public_term
- public_triple_term

## Testing
- [ ] Verified GraphQL queries for all affected relationships
- [ ] Ran integration tests
- [ ] Tested relationship traversals in both directions

## Related Issues
[Link to any related issues]

@claude

claude Bot commented Dec 1, 2025

Copy link
Copy Markdown

Pull Request Review: Feat/fixing migrations

Summary

This PR updates Hasura metadata configurations across 11 tables, converting foreign key constraint relationships to manual configurations and adding frontend role permissions that mirror the existing anonymous role.

Code Quality & Best Practices

✅ Positives

  1. Consistent approach: The migration from foreign_key_constraint_on to manual_configuration is applied uniformly across all affected relationships
  2. Clear column mappings: All manual configurations properly specify column_mapping, insertion_order: null, and remote_table
  3. Permission parity: The frontend role permissions are identical to anonymous role, maintaining consistency

🔍 Observations

Relationship Configuration Changes

The PR converts several relationships from automatic foreign key tracking to manual configuration:

public_atom.yaml (lines 20-46):

  • creator: Now manually maps creator_id → account.id
  • term: Now manually maps term_id → term.id
  • value: Now manually maps value_id → atom_value.id

public_atom_value.yaml (lines 12-54):

  • account: Now manually maps account_id → account.id
  • atom: Now manually maps id → atom.term_id ⚠️
  • caip10: Now manually maps caip10_id → caip10.id

public_term.yaml (lines 36-44, 53-61, 164-172):

  • tripleById: Now manually maps id → triple.term_id
  • positions: Now manually maps id → position.term_id
  • vaults: Now manually maps id → vault.term_id

public_triple_term.yaml (lines 11-28):

  • counter_term: Now manually maps counter_term_id → term.id
  • term: Now manually maps term_id → term.id

Potential Issues

⚠️ Critical: Relationship Mapping Concern

Location: infrastructure/hasura/metadata/databases/intuition/tables/public_atom_value.yaml:15-21

The atom relationship mapping appears potentially incorrect:

- name: atom
  using:
    manual_configuration:
      column_mapping:
        id: term_id  # ⚠️ This maps atom_value.id → atom.term_id

Issue: This suggests atom_value.id is used as a foreign key to atom.term_id, which seems unusual. Typically, you would expect either:

  • atom_value.atom_id → atom.id (if there's an atom_id column), OR
  • atom_value.id → atom.value_id (as seen in the reverse relationship in public_atom.yaml)

The relationship in public_atom.yaml shows:

- name: value
  using:
    manual_configuration:
      column_mapping:
        value_id: id  # atom.value_id → atom_value.id

This creates a potential bidirectional inconsistency. Please verify:

  1. Does the atom_value table actually use id as a foreign key to atom.term_id?
  2. Is the schema design intentional where atom_value.id = atom.term_id?
  3. Should this be atom_id: id instead to match conventional patterns?

ℹ️ Minor: Missing id Column

Location: infrastructure/hasura/metadata/databases/intuition/tables/public_atom.yaml:145-165

The frontend role permissions don't include the id column, while most other tables do include their primary keys. Consider if this omission is intentional or should include - id.

Security Considerations

🔒 Frontend Role Permissions Analysis

Positive aspects:

  1. All permissions use filter: {} which is safe in the context where Hasura's JWT/webhook authentication handles access control
  2. Reasonable rate limits are set (100-250 items per query)
  3. Aggregations are appropriately enabled where needed

Recommendations:

  1. Consider row-level security: If the frontend role is used by client applications, you may want to add filters based on user identity, e.g.:

    filter:
      creator_id: {_eq: X-Hasura-User-Id}
  2. Review sensitive columns: Ensure columns like wallet_id, creator_id, transaction_hash, and raw_data should be publicly accessible via the frontend role

  3. Audit aggregations: Tables allowing allow_aggregations: true enable complex queries that could expose aggregate statistics. Verify this is intentional for all tables

  4. Document role purpose: Consider adding comments explaining the distinction between anonymous and frontend roles if they have identical permissions

Performance Considerations

✅ No immediate concerns

  • Manual relationship configurations don't inherently impact performance
  • Query limits (100-250) are reasonable
  • No N+1 query anti-patterns introduced

💡 Suggestions

  1. Monitor query performance after deployment, especially for deeply nested relationships
  2. Consider adding database indexes if manual relationships are querying non-indexed foreign key columns (though this is a DB schema concern, not metadata)

Test Coverage

⚠️ Missing information

The PR doesn't include:

  • Integration tests for the new relationship configurations
  • GraphQL query tests validating the manual relationships work correctly
  • Permission boundary tests for the frontend role

Recommendation: Add tests that verify:

  1. All manual relationships resolve correctly (no broken joins)
  2. The frontend role can query expected data
  3. Nested queries through the new manual relationships work as expected

Example test case:

query TestAtomValueRelationship {
  atom_value(limit: 1) {
    id
    atom {  # Test the manual relationship
      id
      term_id
      label
    }
  }
}

Migration Path Concerns

📋 Questions to address:

  1. Why the migration? - What issue prompted converting FK constraints to manual configs?
  2. Database constraints: Are the underlying FK constraints in PostgreSQL being dropped, or only the Hasura metadata changing?
  3. Backward compatibility: Are there existing queries/apps that might break?
  4. Rollback plan: How would you revert if issues arise in production?

Summary & Recommendations

Must Address

  • Verify the atom_value.atom relationship mapping (id → term_id) is correct
  • Add the missing id column to atom table's frontend permissions if needed

Should Address

  • Add integration tests for manual relationships
  • Document the reason for migrating from FK constraints to manual config
  • Review and document security model for frontend vs anonymous roles
  • Consider adding row-level security filters if needed

Nice to Have

  • Add comments to YAML files explaining the manual configuration rationale
  • Performance testing for complex nested queries
  • Migration rollback documentation

Overall Assessment

The PR demonstrates a systematic approach to updating Hasura metadata configurations. The main concern is the potential relationship mapping issue in atom_value.yaml. Once that's verified/corrected and tests are added, this should be safe to merge.

Recommendation: Request changes to verify the relationship mapping and add tests before merging.

  tables

  - Added frontend role permissions to predicate_object,
  subject_predicate, event
  - Added frontend role to all share_price_change tables
  - Fixed relationships to use manual_configuration instead of
  foreign_key_constraint_on
    (atom, account, predicate_object, subject_predicate
  relationships)
@claude

claude Bot commented Dec 1, 2025

Copy link
Copy Markdown

PR Review: Feat/fixing migrations

Summary

This PR makes significant changes to Hasura metadata configuration, focusing on two main improvements:

  1. Converting foreign key constraint relationships to manual configuration
  2. Adding frontend role permissions across multiple tables

Code Quality & Best Practices

✅ Strengths

  1. Consistent Pattern Application: The migration from foreign_key_constraint_on to manual_configuration is applied consistently across all affected relationships.

  2. Permission Parity: The frontend role permissions mirror the anonymous role permissions, maintaining consistent access patterns.

  3. Comprehensive Coverage: The changes cover 19 table configuration files, ensuring system-wide consistency.

⚠️ Concerns & Recommendations

1. Inconsistent Relationship Configuration Pattern

In public_vault.yaml:13, there's still a foreign_key_constraint_on relationship:

- name: term
  using:
    foreign_key_constraint_on: term_id

While in other files (e.g., public_atom.yaml, public_account.yaml), similar relationships have been converted to manual_configuration. This inconsistency could indicate:

  • An oversight in the migration
  • A deliberate exception that should be documented

Recommendation: Either convert this to manual_configuration for consistency or add a comment explaining why it's different.

2. Missing Context in Commit Messages

The PR description is empty, and commit messages like "Fixing migrations" and "Fixing triggers" don't explain:

  • Why the migration from foreign_key_constraint_on to manual_configuration was necessary
  • What specific issue was being fixed
  • Whether this relates to a Hasura version upgrade or schema changes

Recommendation: Add context to the PR description explaining the motivation for these changes.

3. Potential Breaking Changes

Converting relationship configurations could potentially affect:

  • GraphQL query structure
  • Existing client queries if relationship behavior changes
  • Hasura's automatic query optimization

Recommendation: Confirm that this change is backward-compatible with existing GraphQL queries and document any breaking changes.

4. Permission Security Review Needed

The frontend role is being added with identical permissions to anonymous role across all tables. Questions to address:

  • Is there a functional difference between these roles?
  • Should frontend have more restrictive permissions than anonymous?
  • Are there sensitive fields (e.g., wallet_id, creator_id) that should have different access levels?

Recommendation: Review whether all exposed columns are appropriate for frontend access, especially in tables like atom, account, and position.

5. Column Mapping Validation

In several files, relationships use column mappings like:

column_mapping:
  atom_id: term_id  # public_account.yaml
  value_id: id      # public_atom.yaml
  term_id: id       # public_term.yaml

Recommendation: Ensure these mappings align with actual database foreign key constraints to avoid runtime errors.

Performance Considerations

  1. Manual Configuration Impact: Manual relationship configuration may disable some of Hasura's automatic optimizations. Monitor query performance after deployment.

  2. Aggregation Limits: All permissions include allow_aggregations: true with limits (100-1000). Ensure these limits are appropriate for expected query patterns.

Security Concerns

Medium Priority

  1. Broad Frontend Access: The frontend role has access to potentially sensitive data:

    • Transaction hashes
    • Wallet IDs
    • Creator IDs
    • Raw blockchain data
  2. No Row-Level Security: All permissions use filter: {}, meaning no row-level filtering. Consider whether the frontend should have unrestricted access to all rows.

  3. Aggregation Exposure: allow_aggregations: true could enable data mining or inference attacks on sensitive information.

Recommendation: Implement row-level security policies if needed, especially for user-specific data.

Test Coverage

⚠️ Missing

  • No test files included in this PR
  • No integration tests for GraphQL queries using these new configurations
  • No migration validation tests

Recommendation: Add tests that:

  1. Verify relationships work correctly after migration
  2. Confirm frontend role permissions function as expected
  3. Validate that existing queries still work

Additional Observations

  1. File Count: 19 files modified with 421 additions and 40 deletions—a significant metadata change that warrants thorough testing.

  2. Share Price Stats Tables: All four time-based aggregation tables (daily, hourly, monthly, weekly) receive identical permission updates—good consistency.

  3. Manual Configuration Verbosity: The new manual configuration is more verbose but more explicit, which can be beneficial for maintenance.

Action Items

Before merging:

  • Add PR description explaining the motivation and context
  • Verify all foreign_key_constraint_on relationships are intentionally converted or left unchanged
  • Review security implications of frontend role permissions
  • Add integration tests for critical GraphQL queries
  • Test in staging environment with actual frontend queries
  • Document any breaking changes in migration notes
  • Confirm performance impact is acceptable

Overall Assessment

The PR demonstrates good execution of a systematic migration pattern, but lacks context and testing. The changes appear technically sound but require validation and security review before production deployment.

Recommendation: Request additional context, add tests, and verify security implications before merging.


Review generated by Claude Code

@claude

claude Bot commented Dec 2, 2025

Copy link
Copy Markdown

Pull Request Review: Feat/fixing migrations (#178)

Summary

This PR standardizes Hasura metadata configurations by converting relationships from foreign_key_constraint_on to manual_configuration and adding frontend role permissions across 23 tables. The changes include 495 additions and 40 deletions.


📊 Changes Overview

1. Relationship Configuration Migration

Pattern: Converting from automatic foreign key tracking to explicit manual configuration

Files affected: 23 table metadata files

  • public_account.yaml
  • public_atom.yaml
  • public_atom_value.yaml
  • public_deposit.yaml
  • public_event.yaml
  • public_fee_transfer.yaml
  • public_organization.yaml
  • public_person.yaml
  • public_position.yaml
  • public_predicate_object.yaml
  • public_redemption.yaml
  • public_share_price_change.yaml
  • public_share_price_change_stats_* (4 files)
  • public_signal.yaml
  • public_subject_predicate.yaml
  • public_term.yaml
  • public_thing.yaml
  • public_triple.yaml
  • public_triple_term.yaml
  • public_vault.yaml

2. Permission Addition

Adding frontend role with identical permissions to anonymous role across all 23 tables


✅ Strengths

1. Consistent Pattern Application

The conversion follows a systematic approach across all files:

Before:

- name: creator
  using:
    foreign_key_constraint_on: creator_id

After:

- name: creator
  using:
    manual_configuration:
      column_mapping:
        creator_id: id
      insertion_order: null
      remote_table:
        name: account
        schema: public

2. Comprehensive Coverage

All relationships that needed conversion appear to have been addressed, showing thorough review of the codebase.

3. Proper Structure

All manual configurations include the required fields:

  • ✅ column_mapping - explicitly defines the relationship
  • ✅ insertion_order: null - appropriate for standard relationships
  • ✅ remote_table - clearly specifies target table and schema

4. Permission Consistency

The frontend role permissions exactly mirror anonymous role permissions, maintaining consistent access patterns.


⚠️ Issues & Concerns

1. Empty PR Description (High Priority)

The PR has no description explaining:

  • Why this migration was necessary
  • What issue it fixes (despite the title "fixing migrations")
  • Whether there are related database migrations
  • If this is related to a Hasura version upgrade

Recommendation: Add a description explaining the motivation. Possibilities include:

  • Foreign key constraints were removed from the database
  • Hasura auto-detection was failing
  • Migration from one Hasura version to another
  • Aligning with team conventions

2. Duplicate Role Permissions (Medium Priority)

The frontend role has identical permissions to anonymous role across all 23 tables.

Questions:

  • Is this intentional or a preparation for future differentiation?
  • Should frontend have more restrictive permissions?
  • Are these roles used in different contexts (e.g., authenticated vs public)?

Concerns:

# Both roles have identical access:
- role: anonymous
  permission:
    columns: [list]
    filter: {}
    limit: 250
    allow_aggregations: true

- role: frontend  
  permission:
    columns: [list]  # Identical
    filter: {}       # Identical
    limit: 250       # Identical
    allow_aggregations: true  # Identical

Recommendation:

  • If roles will differ in the future, add a comment explaining the plan
  • If they should differ now, implement row-level security (RLS) filters
  • Consider if allow_aggregations: true should be restricted for frontend

3. Sensitive Data Exposure (Medium Priority - Security)

Several tables expose potentially sensitive columns to both anonymous and frontend roles without filters:

Examples:

  • public_atom.yaml:140-148 - Exposes wallet_id, creator_id, raw_data
  • public_account.yaml:100-104 - Exposes all account data
  • public_position.yaml:51-68 - Exposes financial positions without owner filtering
  • public_deposit.yaml:57-75 - Exposes transaction details
  • public_triple.yaml:119-135 - Exposes creator_id, transaction_hash

Recommendation: Review whether these should have row-level security:

# Example: restrict to user's own data
filter:
  creator_id: {_eq: X-Hasura-User-Id}

4. Relationship Mapping Validation (Medium Priority)

Several relationships reference atom table using term_id as the target column:

Examples from the PR:

# public_account.yaml:14-15
column_mapping:
  atom_id: term_id  # References atom.term_id, not atom.id

# public_predicate_object.yaml:13-14  
column_mapping:
  object_id: term_id  # References atom.term_id

# public_subject_predicate.yaml:13-14
column_mapping:
  subject_id: term_id  # References atom.term_id

This pattern appears throughout and suggests:

  • The atom table uses term_id as its primary key OR
  • These are intentional references to a non-primary key column

Verification needed:

  • Ensure atom.term_id has a unique constraint if it's being used as a target
  • Confirm this is the intended relationship structure
  • Check if database indexes exist on these columns for performance

5. Inconsistent Relationship Types (Low Priority)

The PR converts some array relationships to manual configuration (e.g., public_term.yaml:53-61) while leaving others as foreign_key_constraint_on.

Example from public_term.yaml:

# Converted to manual:
- name: positions
  using:
    manual_configuration:
      column_mapping:
        id: term_id

# Left as FK constraint:
- name: redemptions
  using:
    foreign_key_constraint_on:
      column: term_id

Question: Is this intentional or should all relationships be standardized?

6. Missing Test Coverage (High Priority)

No test files are included to verify:

  • ❌ GraphQL queries still work correctly with manual relationships
  • ❌ Nested relationship queries function as expected
  • ❌ Frontend role can access the expected data
  • ❌ Relationship joins produce correct results

Recommendation: Add integration tests, for example:

# Test relationship traversal
query TestAtomRelationships {
  atoms(limit: 5) {
    id
    term_id
    creator {      # Test manual relationship
      id
      label
    }
    term {         # Test manual relationship
      id
      type
    }
    value {        # Test manual relationship
      id
      account_id
    }
  }
}

7. Performance Implications (Medium Priority)

Manual relationships may affect Hasura's query planning differently than automatic FK relationships.

Concerns:

  • Are there database indexes on all foreign key columns?
  • Has query performance been tested with complex nested queries?
  • Could this impact the 300+ events/second throughput mentioned in the architecture docs?

Recommendation:

  • Profile complex GraphQL queries before/after
  • Ensure indexes exist on: atom_id, term_id, creator_id, value_id, etc.
  • Monitor query performance in staging

🔒 Security Considerations

Permission Review Summary

Low Risk Tables (aggregate/stats only):

  • ✅ share_price_change_stats_* - Statistics tables, appropriate for public access
  • ✅ organization, person, thing - Public profile data

Medium Risk Tables (financial/transaction data):

  • ⚠️ deposit, redemption - Transaction details with amounts
  • ⚠️ position - User financial positions
  • ⚠️ vault - Market cap and asset data
  • ⚠️ fee_transfer - Fee transaction data

High Risk Tables (identity/sensitive):

  • 🚨 account - User account data including atom_id, label, type
  • 🚨 atom - Contains wallet_id, raw_data, potentially sensitive metadata
  • 🚨 signal - User behavior/signals with account_id

Recommendations:

  1. Implement RLS for accounts: Users should only see their own data
  2. Review raw_data exposure: Consider if this should be restricted
  3. Audit allow_aggregations: Could enable inferring private information via aggregate queries
  4. Consider rate limiting: 250 items/query × aggregations could enable data scraping

📝 Best Practices & Suggestions

1. Add Migration Documentation

Create a comment in each changed file explaining the migration:

# Migrated from foreign_key_constraint_on to manual_configuration
# Reason: [explanation]
# Date: 2024-12-02
# Related PR: #178

2. Document Role Strategy

Add documentation explaining when to use anonymous vs frontend role:

docs/HASURA_ROLES.md:
- anonymous: Unauthenticated public access
- frontend: Authenticated frontend application access  
- [future differentiation plan]

3. Add Validation Tests

Create metadata validation tests:

// tests/hasura-metadata.test.ts
describe('Hasura Metadata Validation', () => {
  it('all manual relationships have valid remote tables', () => {
    // Validate column_mapping references exist
  });
  
  it('frontend role permissions are properly configured', () => {
    // Ensure RLS is applied where needed
  });
});

4. Performance Monitoring

Set up monitoring for:

  • GraphQL query latency (especially nested queries)
  • Relationship join performance
  • Database query patterns from Hasura

🧪 Testing Checklist

Before merging, verify:

  • Relationship Functionality: All converted relationships work correctly

    # Test each table's relationships
    query TestRelationships {
      atoms { creator { id } term { id } value { id } }
      positions { account { id } term { id } }
      # ... etc
    }
  • Permission Boundaries: Frontend role can access expected data

    # Test with frontend JWT token
    curl -X POST \
      -H "Authorization: Bearer $FRONTEND_TOKEN" \
      -H "Content-Type: application/json" \
      -d '{"query": "{ atoms { id label } }"}' \
      https://hasura.example.com/v1/graphql
  • Performance: Query performance hasn't degraded

    # Compare query plans before/after
    EXPLAIN (ANALYZE, BUFFERS) SELECT ...
  • Integration Tests: Run full integration test suite

    npm run test:integration
  • Staging Deployment: Deploy to staging and monitor for issues


🎯 Overall Assessment

Status: ⚠️ Request Changes

Positive Aspects:

  • ✅ Systematic and consistent approach
  • ✅ Comprehensive coverage across all relevant tables
  • ✅ Proper YAML structure and formatting
  • ✅ Clear pattern that's easy to understand and review

Must Address Before Merge:

  1. Add PR description explaining motivation and context
  2. Add integration tests for relationship functionality
  3. Review security model for sensitive data exposure
  4. Verify relationship mappings (especially term_id references)
  5. Document role differences between anonymous and frontend

Should Address:

  1. Performance testing for complex queries
  2. Add validation tests for metadata integrity
  3. Consider RLS implementation for user-specific data
  4. Verify database indexes exist on FK columns

Nice to Have:

  1. Add inline documentation in YAML files
  2. Create monitoring dashboards for query performance
  3. Document rollback procedures

📌 Action Items

For PR Author:

  1. Add a comprehensive PR description
  2. Explain why manual configuration is needed vs FK constraints
  3. Clarify the purpose of duplicate frontend role permissions
  4. Add relationship functionality tests
  5. Consider security implications of current permissions

For Reviewers:

  1. Verify database schema matches these relationship mappings
  2. Confirm atom.term_id is properly indexed and unique
  3. Review whether sensitive columns should have RLS filters
  4. Test query performance with nested relationships

💬 Questions for Discussion

  1. Migration Context: What issue prompted this change? Was Hasura's auto-detection failing?

  2. Role Strategy: What's the long-term plan for anonymous vs frontend roles?

  3. Security Model: Should users be able to query any account/position/transaction, or should there be RLS?

  4. Database Changes: Were any database-level foreign key constraints removed?

  5. Rollback Plan: How would we revert these changes if issues arise in production?


🚀 Recommendation

This PR represents good progress toward standardizing Hasura metadata configuration. However, it needs:

  • Context and documentation
  • Test coverage
  • Security review
  • Performance validation

Once these items are addressed, this will be a solid improvement to the codebase.

Suggested merge order:

  1. Address PR description and documentation
  2. Add tests for relationship functionality
  3. Review and implement security model
  4. Deploy to staging for validation
  5. Monitor for 24-48 hours
  6. Merge to production with monitoring plan

Generated by Claude Code 🤖

Signed-off-by: Luis Eduardo Boiko Ferreira <luiseduardo.boiko@gmail.com>
@leboiko
leboiko merged commit a8ae06d into v2_0 Jan 12, 2026
1 check passed
@leboiko
leboiko deleted the feat/fixing-migrations branch January 12, 2026 14:51
@claude

claude Bot commented Jan 12, 2026

Copy link
Copy Markdown

PR Review: Feat/fixing migrations (#178)

Executive Summary

This is a major consolidation PR that brings 7 comprehensive database migrations into a unified migration system.

Overall Assessment: ✅ APPROVE with minor recommendations

📊 PR Scope

  • Files Changed: 412 files, 150,542+ lines added
  • 7 Major Migrations: Complete schema, indexes, triggers, materialized views, and maintenance functions

🎯 Strengths

  1. Excellent Migration Organization - Clear sequential numbering with descriptive names
  2. Comprehensive Documentation - Function comments, inline docs, dedicated POSITION_COUNT_FIX_FUNCTIONS.md
  3. Idempotent Operations - Safe CREATE OR REPLACE and IF NOT EXISTS usage
  4. Position Count Fix Functions - Three well-designed maintenance functions (full, selective, targeted)
  5. Advanced Features - TimescaleDB analytics, pgai vector search, materialized views

🔍 Key Migration: Position Count Fix Functions ⭐

What it solves:

  • Position counts drift from actual values during redemptions
  • Cascading updates across 6 related tables were error-prone

Functions provided:

  • fix_all_position_counts(): Full recalculation
  • fix_wrong_position_counts(): Selective optimization
  • fix_position_counts_for_term(term_id): Targeted fixes

Usage recommendations:

  • Daily/weekly: fix_wrong_position_counts()
  • After data migrations: fix_all_position_counts()
  • Specific issues: fix_position_counts_for_term(term_id)

🐛 Issues & Recommendations

High Priority (Before Merge)

  1. Missing Down Migration ⚠️
    • Location: infrastructure/hasura/migrations/intuition/1729947331635_consolidated_triggers/down.sql
    • Issue: Referenced but not included in PR
    • Impact: Cannot rollback trigger changes
    • Action Required: Add the down migration

Medium Priority

  1. Migration Order Dependencies - Add README documenting execution order
  2. Test Coverage - Verify tests cover all migrations and rollback scenarios
  3. Performance Testing - Document expected runtime for different database sizes

🔒 Security

✅ No major concerns - All functions use parameterized queries, no privilege escalation risks

Recommendations:

  • Add function-level permissions (restrict to admin roles)
  • Consider audit logging for maintenance functions

⚡ Performance

  • fix_all_position_counts(): O(n), run during maintenance windows
  • fix_wrong_position_counts(): More efficient, safe for daily/weekly
  • fix_position_counts_for_term(): Fast for single term fixes

📝 Documentation

✅ Excellent existing documentation

Suggested additions:

  • Migration README with execution order and dependencies
  • Runbook for position count maintenance operations

🎯 Final Verdict

Status: ✅ APPROVE WITH CONDITIONS

Excellent engineering work with:

  • Well-organized migration structure
  • Comprehensive schema design
  • Valuable operational tooling
  • Advanced features (vector search, time-series)
  • Good documentation

Blocking Issue: Missing down.sql for consolidated_triggers migration

Once the down migration is added, this is ready to merge! 🚀

👏 Acknowledgments

Outstanding consolidation work! The position count fix functions are particularly well-designed and will provide valuable operational tooling. Great job on bringing the migration system into a clean, maintainable state! 🎉


Generated by Claude Code 🤖

leboiko added a commit that referenced this pull request Jan 12, 2026
* Adding functions to update term_ids

* Adding intructions

* Fixing triggers

* Fixing gitignore

* Remove backup files from git tracking

* Adding system architecture MD file

* Adding docs

* Fixing tags

* Updating docs

* Fixing triple relation

* Fixing migrations

* Updating migrations

* Fix frontend role permissions for Hasura
  tables

  - Added frontend role permissions to predicate_object,
  subject_predicate, event
  - Added frontend role to all share_price_change tables
  - Fixed relationships to use manual_configuration instead of
  foreign_key_constraint_on
    (atom, account, predicate_object, subject_predicate
  relationships)

* Updates

---------

Signed-off-by: Luis Eduardo Boiko Ferreira <luiseduardo.boiko@gmail.com>
leboiko added a commit that referenced this pull request Jan 16, 2026
* Add position PnL storage and query

* Add chart-api PnL endpoints (#187)

* Luis/eng 7988 deploy chart api (#180)

* Adding caip-22

* Refactoring and adding docker missing env vars

* Adding fetch tests

* Addressing comments

* Updating BE requirements

* Adding integration test

* Adding another mutations

* Lates fixes

* Removing unecessary file

* Adding chart-api

* Updating to include hasura actions to expose chart-api

* feat(chart-api): Add graph_type parameter for extensible chart types

Summary of Changes:

Rust code (apps/chart-api/):
- Added GraphType enum with sharePriceChange (default) and totalMarketCap
- Renamed share_price to value in responses (breaking change)
- Made curve_id optional in ChartResponse (null for term-level graphs)
- Added graph_type field to responses
- Updated route to /api/v1/curve/{curve_id}/term/{term_id}/data (singular)
- Cache key now includes graph_type
- Added InvalidGraphType and MissingCurveId errors
- Refactored data_fetcher to use generic queries based on graph type
- Updated gap_filler and svg_generator to use value field

Hasura actions (infrastructure/hasura/metadata/):
- Updated URL path to use singular curve/term
- Added graph_type optional parameter to getChartJson and getChartSvg
- Updated ChartDataPoint.value (renamed from share_price)
- Made ChartDataOutput.curve_id optional

API Usage:
- Default: GET /api/v1/curve/1/term/0x.../data?interval=1d&format=json
- With graph_type: GET /api/v1/curve/1/term/0x.../data?interval=1d&format=json&graph_type=totalMarketCap

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(chart-api): Use correct column name for atom table lookup

The atom table uses `term_id` column, not `id`.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(chart-api): Replace count with start/end params, fix code review issues

- Update Hasura actions to use start/end timestamps instead of count
- Fix README URL pattern (curves→curve, terms→term)
- Remove dead code (default_count, sql_interval methods)
- Fix error message to include svg_json format
- Remove redundant curve_id checks in data_fetcher
- Fix Redis health check to use PING command
- Remove unused schema field from AppState and Env

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(chart-api): Rename start/end to start_time/end_time in Hasura actions

The 'end' keyword is reserved in Kriti template engine, causing parse
errors. Renamed to start_time/end_time to avoid the conflict.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(chart-api): Return JSON error responses for Hasura compatibility

Hasura actions require JSON responses. Changed error responses from
plain text to JSON format with error message and code fields.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(image-guard): Return JSON error responses with proper status codes

- Return 4xx for client errors (invalid input, bad request)
- Return 5xx only for actual server errors
- JSON format with error message and code for Hasura compatibility

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Revert "fix(image-guard): Return JSON error responses with proper status codes"

This reverts commit 1e18413.

* fix(chart-api): Add SVG color validation and dimension limits

Security fixes from code review:
- Validate SVG colors to prevent injection attacks (only allow hex colors
  and whitelisted CSS color names)
- Add dimension limits (100-4000px) to prevent memory exhaustion
- Invalid colors fall back to defaults instead of being passed through

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(chart-api): Address security review - CORS, timeouts, SQL docs

- Add SQL injection safety documentation explaining why dynamic SQL is safe
- Fix CORS to be restrictive by default (empty config = no cross-origin)
- Add Redis connection/response timeouts (10s/5s)
- Add logging for CORS configuration state

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>

* Add PnL chart endpoints

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>

* Luis/eng 7988 deploy chart api (#180)

* Adding caip-22

* Refactoring and adding docker missing env vars

* Adding fetch tests

* Addressing comments

* Updating BE requirements

* Adding integration test

* Adding another mutations

* Lates fixes

* Removing unecessary file

* Adding chart-api

* Updating to include hasura actions to expose chart-api

* feat(chart-api): Add graph_type parameter for extensible chart types

Summary of Changes:

Rust code (apps/chart-api/):
- Added GraphType enum with sharePriceChange (default) and totalMarketCap
- Renamed share_price to value in responses (breaking change)
- Made curve_id optional in ChartResponse (null for term-level graphs)
- Added graph_type field to responses
- Updated route to /api/v1/curve/{curve_id}/term/{term_id}/data (singular)
- Cache key now includes graph_type
- Added InvalidGraphType and MissingCurveId errors
- Refactored data_fetcher to use generic queries based on graph type
- Updated gap_filler and svg_generator to use value field

Hasura actions (infrastructure/hasura/metadata/):
- Updated URL path to use singular curve/term
- Added graph_type optional parameter to getChartJson and getChartSvg
- Updated ChartDataPoint.value (renamed from share_price)
- Made ChartDataOutput.curve_id optional

API Usage:
- Default: GET /api/v1/curve/1/term/0x.../data?interval=1d&format=json
- With graph_type: GET /api/v1/curve/1/term/0x.../data?interval=1d&format=json&graph_type=totalMarketCap

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(chart-api): Use correct column name for atom table lookup

The atom table uses `term_id` column, not `id`.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(chart-api): Replace count with start/end params, fix code review issues

- Update Hasura actions to use start/end timestamps instead of count
- Fix README URL pattern (curves→curve, terms→term)
- Remove dead code (default_count, sql_interval methods)
- Fix error message to include svg_json format
- Remove redundant curve_id checks in data_fetcher
- Fix Redis health check to use PING command
- Remove unused schema field from AppState and Env

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(chart-api): Rename start/end to start_time/end_time in Hasura actions

The 'end' keyword is reserved in Kriti template engine, causing parse
errors. Renamed to start_time/end_time to avoid the conflict.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(chart-api): Return JSON error responses for Hasura compatibility

Hasura actions require JSON responses. Changed error responses from
plain text to JSON format with error message and code fields.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(image-guard): Return JSON error responses with proper status codes

- Return 4xx for client errors (invalid input, bad request)
- Return 5xx only for actual server errors
- JSON format with error message and code for Hasura compatibility

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Revert "fix(image-guard): Return JSON error responses with proper status codes"

This reverts commit 1e18413.

* fix(chart-api): Add SVG color validation and dimension limits

Security fixes from code review:
- Validate SVG colors to prevent injection attacks (only allow hex colors
  and whitelisted CSS color names)
- Add dimension limits (100-4000px) to prevent memory exhaustion
- Invalid colors fall back to defaults instead of being passed through

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(chart-api): Address security review - CORS, timeouts, SQL docs

- Add SQL injection safety documentation explaining why dynamic SQL is safe
- Fix CORS to be restrictive by default (empty config = no cross-origin)
- Add Redis connection/response timeouts (10s/5s)
- Add logging for CORS configuration state

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>

* Luis/eng 8013 document pnl implementation (#182)

* Adding caip-22

* Refactoring and adding docker missing env vars

* Adding fetch tests

* Addressing comments

* Updating BE requirements

* Adding integration test

* Adding another mutations

* Lates fixes

* Removing unecessary file

* Adding chart-api

* Updating to include hasura actions to expose chart-api

* feat(chart-api): Add graph_type parameter for extensible chart types

Summary of Changes:

Rust code (apps/chart-api/):
- Added GraphType enum with sharePriceChange (default) and totalMarketCap
- Renamed share_price to value in responses (breaking change)
- Made curve_id optional in ChartResponse (null for term-level graphs)
- Added graph_type field to responses
- Updated route to /api/v1/curve/{curve_id}/term/{term_id}/data (singular)
- Cache key now includes graph_type
- Added InvalidGraphType and MissingCurveId errors
- Refactored data_fetcher to use generic queries based on graph type
- Updated gap_filler and svg_generator to use value field

Hasura actions (infrastructure/hasura/metadata/):
- Updated URL path to use singular curve/term
- Added graph_type optional parameter to getChartJson and getChartSvg
- Updated ChartDataPoint.value (renamed from share_price)
- Made ChartDataOutput.curve_id optional

API Usage:
- Default: GET /api/v1/curve/1/term/0x.../data?interval=1d&format=json
- With graph_type: GET /api/v1/curve/1/term/0x.../data?interval=1d&format=json&graph_type=totalMarketCap

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(chart-api): Use correct column name for atom table lookup

The atom table uses `term_id` column, not `id`.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Adding doc

* Fixing error

* Fixing wording

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>

* docs: hasura graphql (#181)

* docs: hasura docs

* chore: cleanup

* Feat/fixing migrations (#178)

* Adding functions to update term_ids

* Adding intructions

* Fixing triggers

* Fixing gitignore

* Remove backup files from git tracking

* Adding system architecture MD file

* Adding docs

* Fixing tags

* Updating docs

* Fixing triple relation

* Fixing migrations

* Updating migrations

* Fix frontend role permissions for Hasura
  tables

  - Added frontend role permissions to predicate_object,
  subject_predicate, event
  - Added frontend role to all share_price_change tables
  - Fixed relationships to use manual_configuration instead of
  foreign_key_constraint_on
    (atom, account, predicate_object, subject_predicate
  relationships)

* Updates

---------

Signed-off-by: Luis Eduardo Boiko Ferreira <luiseduardo.boiko@gmail.com>

* Complete PnL requirements (#188)

* Address PnL review comments (#189)

* Complete PnL requirements

* Address PnL review feedback

---------

Signed-off-by: Luis Eduardo Boiko Ferreira <luiseduardo.boiko@gmail.com>

* Fixing data fetcher

* Updating migrations

* Addressing comments

* adding new endpoint to fetch raw data

* Adding raw endpoint

---------

Signed-off-by: Luis Eduardo Boiko Ferreira <luiseduardo.boiko@gmail.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Simonas Karuzas <simonas@not.cat>
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.

1 participant