File size: 2,826 Bytes
d99b1af
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';
import path from 'path';

export type SavedFoodReview = {
  id: string;
  userEmail: string;
  submissionId: string;
  campaignSlug: string;
  placeName: string;
  dishName: string;
  privacy: 'private' | 'public';
  createdAt: number;
};

const LOCAL_DATA_DIR = path.join(process.cwd(), '.local-review-data');
const USER_REVIEWS_FILE = path.join(LOCAL_DATA_DIR, 'user-reviews.json');

function ensureLocalDir() {
  mkdirSync(LOCAL_DATA_DIR, { recursive: true });
}

function readAllReviews(): SavedFoodReview[] {
  if (!existsSync(USER_REVIEWS_FILE)) return [];
  try {
    const parsed = JSON.parse(readFileSync(USER_REVIEWS_FILE, 'utf8')) as unknown;
    if (!Array.isArray(parsed)) return [];
    return parsed.filter(isSavedReview);
  } catch {
    return [];
  }
}

function writeAllReviews(reviews: SavedFoodReview[]) {
  ensureLocalDir();
  writeFileSync(USER_REVIEWS_FILE, `${JSON.stringify(reviews, null, 2)}\n`, 'utf8');
}

function isSavedReview(value: unknown): value is SavedFoodReview {
  const maybe = value as Partial<SavedFoodReview>;
  return (
    typeof maybe.id === 'string' &&
    typeof maybe.userEmail === 'string' &&
    typeof maybe.submissionId === 'string' &&
    typeof maybe.campaignSlug === 'string' &&
    typeof maybe.placeName === 'string' &&
    typeof maybe.dishName === 'string' &&
    (maybe.privacy === 'private' || maybe.privacy === 'public') &&
    typeof maybe.createdAt === 'number'
  );
}

function reviewId(userEmail: string, submissionId: string) {
  return `${userEmail.toLowerCase()}:${submissionId}`;
}

export function saveReviewForUser(input: {
  userEmail: string;
  submissionId: string;
  campaignSlug: string;
  placeName?: string | null;
  dishName?: string | null;
}) {
  const userEmail = input.userEmail.trim().toLowerCase();
  if (!userEmail || !input.submissionId) return null;

  const reviews = readAllReviews();
  const id = reviewId(userEmail, input.submissionId);
  const existingIndex = reviews.findIndex((review) => review.id === id);
  const review: SavedFoodReview = {
    id,
    userEmail,
    submissionId: input.submissionId,
    campaignSlug: input.campaignSlug,
    placeName: input.placeName?.trim() || 'Foodstar review',
    dishName: input.dishName?.trim() || 'Micro food review',
    privacy: 'private',
    createdAt: existingIndex >= 0 ? reviews[existingIndex]!.createdAt : Date.now(),
  };

  if (existingIndex >= 0) reviews[existingIndex] = review;
  else reviews.push(review);
  writeAllReviews(reviews);
  return review;
}

export function listReviewsForUser(userEmail: string) {
  const normalized = userEmail.trim().toLowerCase();
  return readAllReviews()
    .filter((review) => review.userEmail === normalized)
    .sort((a, b) => b.createdAt - a.createdAt);
}