Skip to main content

Codebase Architecture Analysis: LIFF Carbon Offset Application

πŸ”— Navigation: πŸ“‹ INDEX | πŸ” Analysis Home | πŸ“ Diary | πŸ“Š Reports

Related Reads: Git History Analysis | LIFF Implementation Review | Environmental Impact Assessment


System Architecture Overview​

High-Level Architecture​

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ LINE App β”‚ β”‚ Cloudflare β”‚ β”‚ Blockchain β”‚
β”‚ β”‚ β”‚ Infrastructure β”‚ β”‚ Networks β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ β”‚ β”‚
β”‚ β”‚ LIFF App │──┼────┼─► Next.js Pages β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚ β”‚ Frontend β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ JBC Chain β”‚ β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ Hono β”‚ β”‚ β”‚ β”‚ (Chain 8899)β”‚ β”‚
β”‚ β”‚ β”‚ β”‚ Workers β”‚ β”œβ”€β”€β”€β”€β”Όβ”€β–Ί NFT Contractsβ”‚ β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚ β”‚ LINE Bot │──┼────┼─► KV Storage β”‚ β”‚ β”‚
β”‚ β”‚ Webhook β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ R2 Storage β”‚ β”‚ β”‚ β”‚ Sichang β”‚ β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ (Images) β”‚ β”‚ β”‚ β”‚ Chain 5151 β”‚ β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ (Backup) β”‚ β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚ β”‚ D1 Database β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”‚ β”‚ (SQLite) β”‚ β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Technology Stack Analysis​

Frontend Layer (Next.js 15.3.2)

// Core Technologies
- React 19.0.0 // Latest React with concurrent features
- Next.js 15.3.2 // App directory, server components
- Tailwind CSS 3.4.17 // Utility-first styling
- TypeScript 5.x // Type safety throughout

// LINE Integration
- @line/liff 2.26.0 // LINE Frontend Framework
- LINE Messaging API // Webhook integration

// Blockchain Integration
- Viem 2.30.6 // Ethereum-compatible client
- Wagmi 2.15.6 // React hooks for Web3
- @thirdweb-dev/sdk // Simplified blockchain operations

Backend Layer (Cloudflare Workers)

// Core Framework
- Hono 4.7.9 // Fast web framework for edge
- Cloudflare Workers // Serverless edge computing

// Storage Strategy
- Cloudflare KV // Global key-value store
- Cloudflare R2 // S3-compatible object storage
- Cloudflare D1 // SQLite at the edge
- Drizzle ORM 0.44.2 // Type-safe database operations

Integration Layer

// Payment Processing
- LINE Webhook API // Receipt image processing
- Credit card gateways // External payment processing

// Blockchain Networks
- JBC Chain (8899) // Primary NFT deployment
- Sichang Chain (5151) // Backup/testing network
- Thirdweb Engine // Wallet management service

Frontend Architecture Deep Dive​

Next.js App Directory Structure​

src/app/
β”œβ”€β”€ (auth)/ # Authentication guard routes
β”œβ”€β”€ admin/ # Admin panel (protected)
β”‚ β”œβ”€β”€ layout.tsx # Admin-specific layout & navigation
β”‚ β”œβ”€β”€ guests/ # Guest management
β”‚ β”‚ β”œβ”€β”€ page.tsx # Guest list with pagination
β”‚ β”‚ └── [id]/ # Individual guest detail
β”‚ β”œβ”€β”€ payments/ # Payment verification interface
β”‚ β”œβ”€β”€ blockchain/ # NFT transfer monitoring
β”‚ β”œβ”€β”€ event-report/ # Analytics dashboard
β”‚ └── qr-generator/ # QR code generation tools
β”œβ”€β”€ carbon-offset/ # Public carbon offset calculator
β”œβ”€β”€ carbon-offset-public/ # Shareable offset pages
β”œβ”€β”€ dashboard/ # User dashboard
β”œβ”€β”€ dinner-talk/ # Event registration
β”‚ └── [id]/ # Individual event pages
β”œβ”€β”€ preview/ # Content preview mode
β”œβ”€β”€ special/ # Special access bypass
└── api/ # API routes (forwarding to Workers)
β”œβ”€β”€ carbon/offset/ # Carbon offset processing
β”œβ”€β”€ dinner-talk/ # Event management
└── wallet/ # Blockchain wallet operations

Component Architecture​

Core Component Patterns

// High-level component organization
src/components/
β”œβ”€β”€ AdminLoginOverlay.tsx # Authentication guard
β”œβ”€β”€ ChainSelector.tsx # Multi-blockchain switching
β”œβ”€β”€ NFTTransferStatus.tsx # Real-time transfer monitoring
β”œβ”€β”€ QRCodeDisplay.tsx # QR code generation & display
β”œβ”€β”€ ShareButton.tsx # Social sharing functionality
β”œβ”€β”€ Toast.tsx # Notification system
└── providers.tsx # Context providers wrapper

// Context Management
src/contexts/
β”œβ”€β”€ AdminAuthContext.tsx # Admin session management
└── ToastContext.tsx # Global notification state

// Custom Hooks
src/hooks/
└── useWallet.ts # Blockchain wallet integration

State Management Strategy

// Local state with React hooks (no global state library)
const [loadingStates, setLoadingStates] = useState({
fetchingGuests: false,
approvingPayment: false,
transferringNFT: false,
generatingQR: false
});

// Context for shared state
const AdminAuthContext = createContext({
isAuthenticated: false,
login: () => {},
logout: () => {},
lastActivity: Date.now()
});

Backend Architecture Deep Dive​

Cloudflare Workers Structure​

workers/
β”œβ”€β”€ index.ts # Main worker entry point
β”œβ”€β”€ routes/ # API route handlers
β”‚ β”œβ”€β”€ admin.ts # Admin operations (1074 changes!)
β”‚ β”œβ”€β”€ admin-db.ts # Database admin operations
β”‚ β”œβ”€β”€ auth.ts # Authentication & wallet creation
β”‚ β”œβ”€β”€ carbon.ts # Carbon offset processing
β”‚ β”œβ”€β”€ carbon-data.ts # Environmental data management
β”‚ β”œβ”€β”€ dashboard.ts # Dashboard statistics
β”‚ β”œβ”€β”€ dinner-talk.ts # Event management
β”‚ β”œβ”€β”€ line-webhook.ts # LINE message processing
β”‚ β”œβ”€β”€ profile.ts # User profile management
β”‚ β”œβ”€β”€ registration.ts # Event registration
β”‚ β”œβ”€β”€ test.ts # Development testing
β”‚ └── wallet.ts # Blockchain operations
β”œβ”€β”€ services/ # Business logic services
β”‚ └── nft-transfer.service.ts # NFT transfer orchestration
└── db/ # Database schema & migrations
β”œβ”€β”€ schema.ts # Drizzle schema definitions
└── migrations/ # SQL migration files

API Architecture Patterns​

RESTful Endpoint Organization

// Admin operations (most complex route file)
app.get('/admin/guests', authMiddleware, paginatedGuestList);
app.get('/admin/guest/:id', authMiddleware, guestDetail);
app.post('/admin/verify-payment', authMiddleware, paymentVerification);
app.post('/admin/reject-payment', authMiddleware, paymentRejection);
app.get('/admin/receipts/:fileName', authMiddleware, receiptImageServing);
app.get('/admin/stats', authMiddleware, dashboardStatistics);

// Carbon offset operations
app.post('/carbon/offset', carbonOffsetPurchase);
app.get('/carbon/offsets/:userId', userOffsetHistory);
app.get('/carbon-data/services', availableServices);
app.get('/carbon-data/service/:serviceId/:duration?', serviceCalculation);

// Blockchain operations
app.post('/wallet/create', walletCreation);
app.get('/wallet/balance/:address', walletBalance);
app.post('/nft/process-next', nftTransferProcessing);

Middleware Pipeline

// Authentication middleware
const authMiddleware = async (c: Context, next: () => Promise<void>) => {
const auth = c.req.header('Authorization');
if (!auth || !validateAdminCredentials(auth)) {
return c.json({ error: 'Unauthorized' }, 401);
}
await next();
};

// CORS middleware
app.use('*', cors({
origin: ['https://liff-carbon-offset-app.pages.dev'],
allowMethods: ['GET', 'POST', 'PUT', 'DELETE'],
allowHeaders: ['Content-Type', 'Authorization']
}));

Data Architecture & Storage Strategy​

Multi-Storage Pattern Analysis​

Cloudflare KV Usage (Fast Access)

// User sessions (global edge distribution)
await USER_KV.put(`user:${userId}`, JSON.stringify({
profile: userProfile,
lastActivity: Date.now(),
sessionId: generateSessionId()
}), { expirationTtl: 3600 });

// Guest registration data (quick lookup)
await GUESTS_KV.put(`guest:${guestId}`, JSON.stringify(guestData));

// Payment metadata (admin performance)
await EVENT_KV.put('payments_metadata', JSON.stringify(allPayments));

Cloudflare R2 Usage (Permanent Storage)

// Receipt images (permanent, large files)
await PAYMENT_RECEIPTS.put(`receipts/${userId}/${timestamp}.jpg`, imageBuffer, {
httpMetadata: {
contentType: 'image/jpeg',
cacheControl: 'public, max-age=31536000'
}
});

// QR code images (shareable content)
await PAYMENT_RECEIPTS.put(`qr-codes/${serviceId}-${amount}.png`, qrBuffer);

Cloudflare D1 Usage (Relational Queries)

// NFT transfer tracking (relational data)
export const nftTransfers = sqliteTable('nft_transfers', {
id: text('id').primaryKey(),
guestId: text('guest_id').notNull(),
tokenId: integer('token_id').notNull(),
chainId: integer('chain_id').notNull(),
status: text('status').notNull(), // pending, submitted, completed, failed
txHash: text('tx_hash'),
createdAt: text('created_at').default(sql`CURRENT_TIMESTAMP`),
completedAt: text('completed_at')
});

// Guest dinner talk registrations
export const dinnerTalkGuests = sqliteTable('dinner_talk_guests', {
id: text('id').primaryKey(),
userId: text('user_id').notNull(),
name: text('name').notNull(),
organization: text('organization'),
registeredAt: text('registered_at').default(sql`CURRENT_TIMESTAMP`),
checkedInAt: text('checked_in_at')
});

Data Flow Architecture​

User Registration Flow

LINE User β†’ LIFF Auth β†’ User Profile Creation β†’ Wallet Generation β†’ Event Registration
↓ ↓ ↓ ↓ ↓
LINE API β†’ KV Storage β†’ Thirdweb Engine β†’ KV Storage β†’ D1 Database

Payment Processing Flow

Receipt Upload β†’ LINE Webhook β†’ Image Download β†’ R2 Storage β†’ Admin Verification β†’ NFT Minting
↓ ↓ ↓ ↓ ↓ ↓
LINE Bot β†’ Cloudflare Worker β†’ LINE API β†’ R2 Bucket β†’ KV Update β†’ Blockchain

Admin Dashboard Flow

Admin Login β†’ Authentication β†’ Data Aggregation β†’ Real-time Updates β†’ Action Processing
↓ ↓ ↓ ↓ ↓
Auth Context β†’ Middleware β†’ Multi-storage Query β†’ Polling β†’ API Calls

Integration Architecture​

LINE Platform Integration​

LIFF (LINE Frontend Framework) Implementation

// Platform-specific initialization
const initializeLiff = async () => {
const isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent);

await liff.init({
liffId: process.env.NEXT_PUBLIC_LIFF_ID,
withLoginOnExternalBrowser: !isIOS // iOS requires internal browser
});

if (!liff.isLoggedIn()) {
liff.login({
redirectUri: window.location.href
});
}

// Get user profile for wallet creation
const profile = await liff.getProfile();
return profile;
};

LINE Bot Webhook Integration

// Secure webhook processing
app.post('/line-webhook', async (c) => {
// Verify LINE signature
const signature = c.req.header('X-Line-Signature');
const body = await c.req.text();

const expectedSignature = crypto
.createHmac('sha256', channelSecret)
.update(body)
.digest('base64');

if (signature !== expectedSignature) {
return c.json({ error: 'Invalid signature' }, 400);
}

// Process image messages (payment receipts)
const events = JSON.parse(body).events;
for (const event of events) {
if (event.type === 'message' && event.message.type === 'image') {
await processReceiptImage(event.message.id, event.source.userId);
}
}

return c.json({ success: true });
});

Blockchain Integration Architecture​

Multi-Chain Support Pattern

// Chain configuration management
const SUPPORTED_CHAINS = {
8899: {
name: 'JIBCHAIN L1',
rpcUrl: 'https://rpc.jibchain.net',
explorerUrl: 'https://exp.jibchain.net',
contracts: {
carbonPass: '0x742d35Cc6634C0532925a3b8D1c9CEA03cF97c2a',
nftManager: '0x...'
},
isPrimary: true
},
5151: {
name: 'Sichang Testnet',
rpcUrl: 'https://rpc.sichang.net',
explorerUrl: 'https://explorer.sichang.net',
contracts: {
carbonPass: '0x456...',
nftManager: '0x789...'
},
isPrimary: false
}
};

// Unified blockchain operations
class BlockchainService {
async mintCarbonNFT(userId: string, amount: number, chainId: number = 8899) {
const chain = SUPPORTED_CHAINS[chainId];
const client = createWalletClient({
chain: {
id: chainId,
name: chain.name,
nativeCurrency: { name: 'ETH', symbol: 'ETH', decimals: 18 },
rpcUrls: { default: { http: [chain.rpcUrl] } }
},
transport: http(chain.rpcUrl)
});

return await client.writeContract({
address: chain.contracts.carbonPass,
abi: carbonPassABI,
functionName: 'mint',
args: [userId, amount]
});
}
}

Performance Architecture​

Edge Computing Optimization

// Smart caching strategy
const getCachedUserData = async (userId: string): Promise<UserData | null> => {
// Try KV first (edge cache)
const cached = await USER_KV.get(`user:${userId}`);
if (cached) {
return JSON.parse(cached);
}

// Fallback to D1 database
const userData = await db.query.users.findFirst({
where: eq(users.id, userId)
});

if (userData) {
// Cache for future requests
await USER_KV.put(`user:${userId}`, JSON.stringify(userData), {
expirationTtl: 3600
});
}

return userData;
};

// Real-time updates without WebSockets
const useRealTimeData = (fetchFunction: Function, interval: number = 30000) => {
const [data, setData] = useState(null);
const [lastUpdate, setLastUpdate] = useState(Date.now());

useEffect(() => {
const update = async () => {
const fresh = await fetchFunction();
setData(fresh);
setLastUpdate(Date.now());
};

update(); // Initial load
const timer = setInterval(update, interval);
return () => clearInterval(timer);
}, []);

return { data, lastUpdate, isStale: Date.now() - lastUpdate > interval };
};

Security Architecture​

Authentication & Authorization​

// Multi-layer authentication
const authenticateRequest = async (request: Request): Promise<AuthResult> => {
// Layer 1: LIFF token validation
const liffToken = request.headers.get('X-LIFF-Token');
if (liffToken) {
const liffUser = await validateLiffToken(liffToken);
if (liffUser) return { type: 'user', userId: liffUser.sub };
}

// Layer 2: Admin credentials
const authHeader = request.headers.get('Authorization');
if (authHeader?.startsWith('Basic ')) {
const adminAuth = await validateAdminCredentials(authHeader);
if (adminAuth) return { type: 'admin', adminId: adminAuth.id };
}

return { type: 'anonymous' };
};

Data Security Patterns​

// Sensitive data encryption
const encryptSensitiveData = (data: object): string => {
return CryptoJS.AES.encrypt(
JSON.stringify(data),
process.env.ENCRYPTION_KEY
).toString();
};

// Audit trail for admin actions
const logAdminAction = async (adminId: string, action: string, details: object) => {
await AUDIT_KV.put(`audit:${Date.now()}:${adminId}`, JSON.stringify({
adminId,
action,
details,
timestamp: new Date().toISOString(),
ip: getClientIP()
}));
};

Architecture Assessment​

Strengths​

  1. Edge-First Design - Optimal performance through Cloudflare edge network
  2. Multi-Storage Strategy - Right storage type for each data pattern
  3. Mobile-First Integration - Deep LINE platform integration
  4. Blockchain Abstraction - Multi-chain support with unified interface
  5. Production Security - Multi-layer authentication and audit trails

Complexity Areas​

  1. Admin Route Complexity - 1074 changes indicate ongoing business logic evolution
  2. Payment Processing - Complex approval workflows for real-world scenarios
  3. Real-Time Updates - Polling-based approach instead of WebSockets
  4. Cross-Platform Handling - iOS vs Android LIFF behavior differences

Scalability Considerations​

  • Edge computing enables global scale
  • KV storage provides sub-millisecond access worldwide
  • D1 database may become bottleneck for complex queries
  • Polling approach limits real-time responsiveness

This architecture represents a production-grade LIFF application that successfully integrates mobile-first design, blockchain operations, environmental impact tracking, and complex payment processing workflows.


This analysis is based on examination of 278 commits, 8 tracked directories, and comprehensive codebase exploration of a real-world LIFF carbon offset application.