← 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;
}