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_SECRETvia 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 Pattern | Data Type | Description |
|---|---|---|
profile:{addr} | Object | User profile |
quests | Array | All quests |
leaderboard | Object | Rankings |
mail:{addr} | Array | User mailbox (encrypted) |
mail:broadcasts | Array | Platform announcements |
communityDao | Object | DAO state |