← back to Wine Finder Next
src/types/membership.ts
239 lines
// Tokenized Wine Membership System Types
export interface Bottle {
id: string;
name: string;
vintage: number;
producer: string;
region: string;
size: string; // e.g., "750ml"
totalMembershipUnits: number;
availableMembershipUnits: number;
estimatedValue: number;
imageUrl?: string;
description?: string;
provenance: string;
status: 'active' | 'locked' | 'unlocked' | 'depleted';
createdAt: Date;
updatedAt: Date;
}
export interface MembershipUnit {
id: string;
bottleId: string;
tokenId: string; // Unique blockchain/token identifier
ownerId: string;
ownerEmail: string;
ownerName: string;
purchasePrice: number;
purchaseDate: Date;
status: 'active' | 'locked' | 'redeemed';
votingPower: number; // Usually 1 per unit
transactionHistory: Transaction[];
}
export interface Transaction {
id: string;
type: 'purchase' | 'transfer' | 'trade' | 'redemption';
fromUserId?: string;
toUserId: string;
membershipUnitId: string;
price?: number;
timestamp: Date;
txHash?: string; // If using blockchain
}
export interface GovernanceVote {
id: string;
bottleId: string;
proposal: string;
proposalType: 'unlock' | 'event' | 'other';
description: string;
startDate: Date;
endDate: Date;
status: 'active' | 'passed' | 'failed' | 'executed';
votesFor: number;
votesAgainst: number;
votesAbstain: number;
quorumRequired: number; // Percentage
approvalThreshold: number; // Percentage
votes: Vote[];
createdBy: string;
executedAt?: Date;
}
export interface Vote {
id: string;
voteId: string;
userId: string;
membershipUnitId: string;
choice: 'for' | 'against' | 'abstain';
votingPower: number;
timestamp: Date;
signature?: string;
}
export interface SampleUnit {
id: string;
bottleId: string;
sampleNumber: number; // e.g., #1 of 100
size: string; // e.g., "50ml"
status: 'available' | 'reserved' | 'shipped' | 'redeemed';
digitalRecordId: string;
assignedTo?: string; // User ID
createdFromVoteId: string;
createdAt: Date;
redeemedAt?: Date;
}
export interface SampleRight {
id: string;
sampleUnitId: string;
bottleId: string;
ownerId: string;
ownerEmail: string;
status: 'active' | 'listed' | 'redeemed' | 'transferred';
acquisitionPrice?: number;
currentMarketPrice?: number;
canRedeem: boolean;
transferHistory: SampleTransfer[];
createdAt: Date;
}
export interface SampleTransfer {
id: string;
sampleRightId: string;
fromUserId: string;
toUserId: string;
price: number;
timestamp: Date;
status: 'pending' | 'completed' | 'cancelled';
}
export interface MarketplaceListing {
id: string;
listingType: 'membership' | 'sample-right';
itemId: string; // MembershipUnit ID or SampleRight ID
bottleId: string;
sellerId: string;
sellerName: string;
price: number;
currency: 'USD';
status: 'active' | 'sold' | 'cancelled' | 'expired';
listedAt: Date;
expiresAt?: Date;
soldAt?: Date;
soldTo?: string;
}
export interface FulfillmentRequest {
id: string;
sampleRightId: string;
sampleUnitId: string;
userId: string;
userEmail: string;
shippingAddress: ShippingAddress;
status: 'pending' | 'compliance_check' | 'approved' | 'processing' | 'shipped' | 'delivered' | 'rejected';
partnerOrderId?: string;
trackingNumber?: string;
complianceCheckResults?: ComplianceCheck;
createdAt: Date;
processedAt?: Date;
shippedAt?: Date;
deliveredAt?: Date;
rejectionReason?: string;
}
export interface ShippingAddress {
name: string;
addressLine1: string;
addressLine2?: string;
city: string;
state: string;
zipCode: string;
country: string;
phone: string;
}
export interface ComplianceCheck {
age21Plus: boolean;
stateAllowed: boolean;
licensedDistributorAvailable: boolean;
specialPermitsRequired: boolean;
notes?: string;
checkedAt: Date;
checkedBy: string;
}
export interface FulfillmentPartner {
id: string;
name: string;
licenseNumber: string;
licenseState: string;
serviceStates: string[]; // States they can ship to
apiEndpoint: string;
apiKey?: string;
contactEmail: string;
contactPhone: string;
capabilities: string[]; // e.g., ['sampling', 'shipping', 'events']
active: boolean;
}
export interface DigitalRecord {
id: string;
recordType: 'bottle' | 'membership' | 'sample' | 'transaction';
entityId: string;
data: any;
hash?: string; // Cryptographic hash for integrity
previousHash?: string; // Chain records together
timestamp: Date;
signature?: string;
metadata?: {
[key: string]: any;
};
}
export interface UserProfile {
id: string;
email: string;
name: string;
walletAddress?: string;
joinDate: Date;
membershipUnits: MembershipUnit[];
sampleRights: SampleRight[];
voteHistory: Vote[];
transactionHistory: Transaction[];
complianceStatus: {
age21Verified: boolean;
stateOfResidence: string;
verificationDate?: Date;
};
}
// API Response Types
export interface ApiResponse<T> {
success: boolean;
data?: T;
error?: string;
message?: string;
}
export interface PaginatedResponse<T> {
items: T[];
total: number;
page: number;
pageSize: number;
hasMore: boolean;
}
// Platform Configuration
export interface PlatformConfig {
votingQuorumPercentage: number;
votingApprovalThreshold: number;
votingPeriodDays: number;
sampleSizeML: number;
platformFeePercentage: number;
minimumListingPrice: number;
maximumListingDays: number;
}