Skip to content

Database Schemas

All data is stored in Vercel KV (Redis) in production. LocalStorage is used only as a cache to reduce API calls and provide instant UI on load. The database is always the source of truth.

Profile Schema

Key: profile:{address} (address lowercase)

typescript
interface Profile {
  address: string;                    // Ethereum address (checksummed)
  ensAddress: string | null;          // ENS name if detected
  profilePhoto: string | null;        // Photo identifier
  githubUsername: string | null;      // Linked GitHub username
  yearJoined: number;                 // Year registered
  mailLastReadAt: string | null;      // ISO timestamp
  
  activeQuests: ActiveQuestEntry[];   // Quests user is working on
  badges: Badge[];                    // Earned badges
  
  highestRanks: {
    farmer: string | null;            // 'novice' | 'apprentice' | 'journeyman' | 'master' | 'grandmaster'
    giver: string | null;             // 'early' | 'patron' | 'sponsor' | 'benefactor' | 'philanthropist'
    guild: string | null;
    benevolent: string | null;
  };
  
  guild: string | null;               // Guild membership
  
  genesisDAO: {
    isMember: boolean;
    title: string | null;             // Role title
    nftTokenId: string | null;
    nftTxHash: string | null;
  };
  
  incentiveShares: {
    isHolder: boolean;
    numberOfShares: number;
  };
  
  numberOfSeasonsCompleted: number;
  currentSeason: number;
  
  farmerProfile: {
    rank: string;
    questsCompleted: number;
    earnings: number;                 // Total USDC earned
    rating: number;                   // 0-5 stars
    skills: string[];
  };
  
  giverProfile: {
    rank: string;
    questsPosted: number;
    questsCompleted: number;
    totalPaid: number;                // Total USDC paid out
    rating: number;
  };
  
  reputation: {
    reviewsGiven: Review[];
    reviewsReceived: Review[];
    benevolenceScore: number;
    negativeRep: number;
    negativeReports: Report[];
  };
  
  kyc: {
    taxDocuments: TaxDoc[];
    totalEarned: number;
    earnedCurrentSeason: number;
    earnedHistory: SeasonRecord[];
    totalGiven: number;
    givenCurrentSeason: number;
    givenHistory: SeasonRecord[];
    delegatedGiven: number;
    delegatedCurrentSeason: number;
    delegatedHistory: SeasonRecord[];
  };
  
  createdAt: string;                  // ISO timestamp
  updatedAt: string;                  // ISO timestamp
}

interface ActiveQuestEntry {
  questId: string;
  title: string;
  status: 'in-progress' | 'submitted' | 'completed';
  reward: string;
  acceptedAt: string;
}

Quest Schema

Key: quests (array of all quests)

typescript
interface Quest {
  id: string;                         // 'quest-{timestamp}-{rand}'
  title: string;
  description: string;
  reward: string;                     // '100 USDC'
  rewardAmount: number;
  rewardToken: string;                // 'USDC'
  
  deadline: string | null;            // ISO timestamp
  duration: string | null;            // '2 weeks'
  
  giver: string;                      // Display name
  giverAddress: string;               // Ethereum address
  
  githubRepo: string | null;          // 'owner/repo'
  githubIssue: string | null;         // Issue URL or number
  
  skills: string[];                   // ['TypeScript', 'React']
  minRank: string;                    // Minimum farmer rank
  mode: 'open' | 'invite' | 'guild';
  maxFarmers: number;
  activeFarmers: number;
  
  status: 'open' | 'in-progress' | 'review' | 'completed' | 'cancelled';
  
  bonus: string | null;               // Bonus reward description
  category: string;                   // 'Frontend', 'Backend', etc.
  visibility: 'public' | 'private';
  season: number;
  
  createdAt: string;
  updatedAt: string;
}

Mail Schema

Key: mail:{address} (per-user mailbox, encrypted)

typescript
interface MailMessage {
  id: string;                         // 'mail-{timestamp}-{rand}'
  from: string;                       // Sender address
  to: string;                         // Recipient address or '*' for broadcast
  subject: string;                    // Encrypted in KV
  body: string;                       // Encrypted in KV
  type: 'direct' | 'quest' | 'platform-update' | 'dispute';
  sentAt: string;                     // ISO timestamp
  read: boolean;
  _encrypted?: boolean;               // Internal flag
}

Encryption

Mail uses AES-256-GCM encryption:

  • Key derived from JWT_SECRET via SHA-256
  • Format: {iv_base64}:{authTag_base64}:{ciphertext_base64}
  • Encrypted fields: subject, body

Community DAO Schema

Key: communityDao

typescript
interface CommunityDao {
  genesisCreator: {
    address: string;
    ensAddress: string | null;
    website: string | null;
    nftTokenId: string | null;
  };
  
  members: DaoMember[];
  pastMembers: DaoMember[];
  
  treasury: {
    walletAddress: string;
    balance: number;
    totalIncome: number;
    totalExpenses: number;
    records: TreasuryRecord[];
  };
  
  fqps: FetchQuestProposal[];         // Fetch Quest Proposals
  rfps: RequestForProposal[];
  
  season: number;
  createdAt: string;
  updatedAt: string;
}

interface DaoMember {
  address: string;
  ensAddress: string | null;
  role: string;                       // 'Genesis Creator', 'Core Contributor', etc.
  nftTokenId: string | null;
  incomeAllocation: number;           // Percentage
  joinedAt: string;
  profilePhoto: string | null;
}

interface FetchQuestProposal {
  id: string;                         // 'FQP-001'
  title: string;
  description: string;
  author: string;                     // Address
  authorEns: string | null;
  status: 'new' | 'discussion' | 'voting' | 'passed' | 'rejected' | 'implemented';
  category: string;
  discussionEndDate: string;
  voteEndDate: string | null;
  noticeEndDate: string | null;
  votesFor: number;
  votesAgainst: number;
  createdAt: string;
  updatedAt: string;
}

Leaderboard Schema

Key: leaderboard

typescript
interface Leaderboard {
  farmers: LeaderboardEntry[];
  givers: LeaderboardEntry[];
  guilds: GuildEntry[];
  season: {
    number: number;
    startDate: string;
    endDate: string;
  };
}

interface LeaderboardEntry {
  address: string;
  ensAddress: string | null;
  profilePhoto: string | null;
  rank: string;
  score: number;
  questsCompleted?: number;
  questsPosted?: number;
  earnings?: number;
  totalPaid?: number;
}

KV Key Reference

Key PatternData TypeDescription
profile:{addr}ObjectUser profile
questsArrayAll quests
leaderboardObjectRankings
mail:{addr}ArrayUser mailbox (encrypted)
mail:broadcastsArrayPlatform announcements
communityDaoObjectDAO state

Fetch Quests — Decentralized Gig-Work Platform