Skip to content

Commit c888aa6

Browse files
authored
Merge pull request #406 from PolicyEngine/feat/rename-reports
Allow renaming of all ingredient types
2 parents 2063038 + 6f57c7d commit c888aa6

29 files changed

+1913
-267
lines changed

app/src/api/geographicAssociation.ts

Lines changed: 46 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,12 @@ export interface UserGeographicStore {
55
create: (population: UserGeographyPopulation) => Promise<UserGeographyPopulation>;
66
findByUser: (userId: string, countryId?: string) => Promise<UserGeographyPopulation[]>;
77
findById: (userId: string, geographyId: string) => Promise<UserGeographyPopulation | null>;
8+
update: (
9+
userId: string,
10+
geographyId: string,
11+
updates: Partial<UserGeographyPopulation>
12+
) => Promise<UserGeographyPopulation>;
813
// The below are not yet implemented, but keeping for future use
9-
// update(userId: string, geographyId: string, updates: Partial<UserGeographyPopulation>): Promise<UserGeographyPopulation>;
1014
// delete(userId: string, geographyId: string): Promise<void>;
1115
}
1216

@@ -67,22 +71,25 @@ export class ApiGeographicStore implements UserGeographicStore {
6771
return UserGeographicAdapter.fromApiResponse(apiData);
6872
}
6973

70-
// Not yet implemented, but keeping for future use
71-
/*
72-
async update(userId: string, geographyId: string, updates: Partial<UserGeographyPopulation>): Promise<UserGeographyPopulation> {
73-
const response = await fetch(`/api/user-geographic-associations/${userId}/${geographyId}`, {
74-
method: 'PUT',
75-
headers: { 'Content-Type': 'application/json' },
76-
body: JSON.stringify(updates),
77-
});
78-
79-
if (!response.ok) {
80-
throw new Error('Failed to update association');
81-
}
74+
async update(
75+
_userId: string,
76+
_geographyId: string,
77+
_updates: Partial<UserGeographyPopulation>
78+
): Promise<UserGeographyPopulation> {
79+
// TODO: Implement when backend API endpoint is available
80+
// Expected endpoint: PUT /api/user-geographic-associations/:userId/:geographyId
81+
// Expected payload: UserGeographicUpdatePayload (to be created)
82+
83+
console.warn(
84+
'[ApiGeographicStore.update] API endpoint not yet implemented. ' +
85+
'This method will be activated when user authentication is added.'
86+
);
8287

83-
return response.json();
88+
throw new Error(
89+
'Geographic population updates via API are not yet supported. ' +
90+
'Please ensure you are using localStorage mode.'
91+
);
8492
}
85-
*/
8693

8794
// Not yet implemented, but keeping for future use
8895
/*
@@ -136,23 +143,36 @@ export class LocalStorageGeographicStore implements UserGeographicStore {
136143
return populations.find((p) => p.userId === userId && p.geographyId === geographyId) || null;
137144
}
138145

139-
// Not yet implemented, but keeping for future use
140-
/*
141-
async update(userId: string, geographyId: string, updates: Partial<UserGeographyPopulation>): Promise<UserGeographyPopulation> {
146+
async update(
147+
userId: string,
148+
geographyId: string,
149+
updates: Partial<UserGeographyPopulation>
150+
): Promise<UserGeographyPopulation> {
142151
const populations = this.getStoredPopulations();
143-
const index = populations.findIndex(p => p.userId === userId && p.geographyId === geographyId);
144-
152+
153+
// Find by userId and geographyId composite key
154+
const index = populations.findIndex(
155+
(g) => g.userId === userId && g.geographyId === geographyId
156+
);
157+
145158
if (index === -1) {
146-
throw new Error('Geographic population not found');
159+
throw new Error(
160+
`UserGeography with userId ${userId} and geographyId ${geographyId} not found`
161+
);
147162
}
148163

149-
const updatedPopulation = { ...populations[index], ...updates };
150-
populations[index] = updatedPopulation;
151-
164+
// Merge updates and set timestamp
165+
const updated: UserGeographyPopulation = {
166+
...populations[index],
167+
...updates,
168+
updatedAt: new Date().toISOString(),
169+
};
170+
171+
populations[index] = updated;
152172
this.setStoredPopulations(populations);
153-
return updatedPopulation;
173+
174+
return updated;
154175
}
155-
*/
156176

157177
// Not yet implemented, but keeping for future use
158178
/*

app/src/api/householdAssociation.ts

Lines changed: 39 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,11 @@ export interface UserHouseholdStore {
55
create: (association: UserHouseholdPopulation) => Promise<UserHouseholdPopulation>;
66
findByUser: (userId: string, countryId?: string) => Promise<UserHouseholdPopulation[]>;
77
findById: (userId: string, householdId: string) => Promise<UserHouseholdPopulation | null>;
8+
update: (
9+
userHouseholdId: string,
10+
updates: Partial<UserHouseholdPopulation>
11+
) => Promise<UserHouseholdPopulation>;
812
// The below are not yet implemented, but keeping for future use
9-
// update(userId: string, householdId: string, updates: Partial<UserHouseholdPopulation>): Promise<UserHouseholdPopulation>;
1013
// delete(userId: string, householdId: string): Promise<void>;
1114
}
1215

@@ -64,22 +67,24 @@ export class ApiHouseholdStore implements UserHouseholdStore {
6467
return UserHouseholdAdapter.fromApiResponse(apiData);
6568
}
6669

67-
// Not yet implemented, but keeping for future use
68-
/*
69-
async update(userId: string, householdId: string, updates: Partial<UserHousehold>): Promise<UserHousehold> {
70-
const response = await fetch(`/api/user-population-households/${userId}/${householdId}`, {
71-
method: 'PUT',
72-
headers: { 'Content-Type': 'application/json' },
73-
body: JSON.stringify(updates),
74-
});
75-
76-
if (!response.ok) {
77-
throw new Error('Failed to update association');
78-
}
70+
async update(
71+
_userHouseholdId: string,
72+
_updates: Partial<UserHouseholdPopulation>
73+
): Promise<UserHouseholdPopulation> {
74+
// TODO: Implement when backend API endpoint is available
75+
// Expected endpoint: PUT /api/user-household-associations/:userHouseholdId
76+
// Expected payload: UserHouseholdUpdatePayload (to be created)
77+
78+
console.warn(
79+
'[ApiHouseholdStore.update] API endpoint not yet implemented. ' +
80+
'This method will be activated when user authentication is added.'
81+
);
7982

80-
return response.json();
83+
throw new Error(
84+
'Household updates via API are not yet supported. ' +
85+
'Please ensure you are using localStorage mode.'
86+
);
8187
}
82-
*/
8388

8489
// Not yet implemented, but keeping for future use
8590
/*
@@ -134,23 +139,31 @@ export class LocalStorageHouseholdStore implements UserHouseholdStore {
134139
return households.find((h) => h.userId === userId && h.householdId === householdId) || null;
135140
}
136141

137-
// Not yet implemented, but keeping for future use
138-
/*
139-
async update(userId: string, householdId: string, updates: Partial<UserHousehold>): Promise<UserHousehold> {
142+
async update(
143+
userHouseholdId: string,
144+
updates: Partial<UserHouseholdPopulation>
145+
): Promise<UserHouseholdPopulation> {
140146
const households = this.getStoredHouseholds();
141-
const index = households.findIndex(a => a.userId === userId && a.householdId === householdId);
142-
147+
148+
// Find by userHousehold.id (the "suh-" prefixed ID), NOT householdId
149+
const index = households.findIndex((h) => h.id === userHouseholdId);
150+
143151
if (index === -1) {
144-
throw new Error('Association not found');
152+
throw new Error(`UserHousehold with id ${userHouseholdId} not found`);
145153
}
146154

147-
const updatedAssociation = { ...households[index], ...updates };
148-
households[index] = updatedAssociation;
149-
155+
// Merge updates and set timestamp
156+
const updated: UserHouseholdPopulation = {
157+
...households[index],
158+
...updates,
159+
updatedAt: new Date().toISOString(),
160+
};
161+
162+
households[index] = updated;
150163
this.setStoredHouseholds(households);
151-
return updatedAssociation;
164+
165+
return updated;
152166
}
153-
*/
154167

155168
// Not yet implemented, but keeping for future use
156169
/*

app/src/api/policyAssociation.ts

Lines changed: 26 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ export interface UserPolicyStore {
66
create: (policy: Omit<UserPolicy, 'id' | 'createdAt'>) => Promise<UserPolicy>;
77
findByUser: (userId: string, countryId?: string) => Promise<UserPolicy[]>;
88
findById: (userId: string, policyId: string) => Promise<UserPolicy | null>;
9+
update: (userPolicyId: string, updates: Partial<UserPolicy>) => Promise<UserPolicy>;
910
// The below are not yet implemented, but keeping for future use
10-
// update(userId: string, policyId: string, updates: Partial<UserPolicy>): Promise<UserPolicy>;
11-
// delete(userId: string, policyId: string): Promise<void>;
11+
// delete(userPolicyId: string): Promise<void>;
1212
}
1313

1414
export class ApiPolicyStore implements UserPolicyStore {
@@ -64,22 +64,21 @@ export class ApiPolicyStore implements UserPolicyStore {
6464
return UserPolicyAdapter.fromApiResponse(apiData);
6565
}
6666

67-
// Not yet implemented, but keeping for future use
68-
/*
69-
async update(userId: string, policyId: string, updates: Partial<UserPolicy>): Promise<UserPolicy> {
70-
const response = await fetch(`/api/user-policy-associations/${userId}/${policyId}`, {
71-
method: 'PUT',
72-
headers: { 'Content-Type': 'application/json' },
73-
body: JSON.stringify(updates),
74-
});
67+
async update(_userPolicyId: string, _updates: Partial<UserPolicy>): Promise<UserPolicy> {
68+
// TODO: Implement when backend API endpoint is available
69+
// Expected endpoint: PUT /api/user-policy-associations/:userPolicyId
70+
// Expected payload: UserPolicyUpdatePayload (to be created)
7571

76-
if (!response.ok) {
77-
throw new Error('Failed to update association');
78-
}
72+
console.warn(
73+
'[ApiPolicyStore.update] API endpoint not yet implemented. ' +
74+
'This method will be activated when user authentication is added.'
75+
);
7976

80-
return response.json();
77+
throw new Error(
78+
'Policy updates via API are not yet supported. ' +
79+
'Please ensure you are using localStorage mode.'
80+
);
8181
}
82-
*/
8382

8483
// Not yet implemented, but keeping for future use
8584
/*
@@ -155,25 +154,28 @@ export class LocalStoragePolicyStore implements UserPolicyStore {
155154
localStorage.setItem(this.STORAGE_KEY, JSON.stringify(policies));
156155
}
157156

158-
// Not yet implemented, but keeping for future use
159-
/*
160-
async update(userId: string, policyId: string, updates: Partial<UserPolicy>): Promise<UserPolicy> {
157+
async update(userPolicyId: string, updates: Partial<UserPolicy>): Promise<UserPolicy> {
161158
const policies = this.getStoredPolicies();
162-
const index = policies.findIndex(
163-
a => a.userId === userId && a.policyId === policyId
164-
);
159+
160+
// Find by userPolicy.id (the "sup-" prefixed ID), NOT policyId
161+
const index = policies.findIndex((p) => p.id === userPolicyId);
165162

166163
if (index === -1) {
167-
throw new Error('Association not found');
164+
throw new Error(`UserPolicy with id ${userPolicyId} not found`);
168165
}
169166

170-
const updated = { ...policies[index], ...updates };
167+
// Merge updates and set timestamp
168+
const updated: UserPolicy = {
169+
...policies[index],
170+
...updates,
171+
updatedAt: new Date().toISOString(),
172+
};
173+
171174
policies[index] = updated;
172175
this.setStoredPolicies(policies);
173176

174177
return updated;
175178
}
176-
*/
177179

178180
// Not yet implemented, but keeping for future use
179181
/*

app/src/api/reportAssociation.ts

Lines changed: 26 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ export interface UserReportStore {
77
findByUser: (userId: string, countryId?: string) => Promise<UserReport[]>;
88
findById: (userId: string, reportId: string) => Promise<UserReport | null>;
99
findByUserReportId: (userReportId: string) => Promise<UserReport | null>;
10+
update: (userReportId: string, updates: Partial<UserReport>) => Promise<UserReport>;
1011
// The below are not yet implemented, but keeping for future use
11-
// update(userId: string, reportId: string, updates: Partial<UserReport>): Promise<UserReport>;
12-
// delete(userId: string, reportId: string): Promise<void>;
12+
// delete(userReportId: string): Promise<void>;
1313
}
1414

1515
export class ApiReportStore implements UserReportStore {
@@ -83,22 +83,21 @@ export class ApiReportStore implements UserReportStore {
8383
return UserReportAdapter.fromApiResponse(apiData);
8484
}
8585

86-
// Not yet implemented, but keeping for future use
87-
/*
88-
async update(userId: string, reportId: string, updates: Partial<UserReport>): Promise<UserReport> {
89-
const response = await fetch(`/api/user-report-associations/${userId}/${reportId}`, {
90-
method: 'PUT',
91-
headers: { 'Content-Type': 'application/json' },
92-
body: JSON.stringify(updates),
93-
});
86+
async update(_userReportId: string, _updates: Partial<UserReport>): Promise<UserReport> {
87+
// TODO: Implement when backend API endpoint is available
88+
// Expected endpoint: PUT /api/user-report-associations/:userReportId
89+
// Expected payload: UserReportUpdatePayload (to be created)
9490

95-
if (!response.ok) {
96-
throw new Error('Failed to update association');
97-
}
91+
console.warn(
92+
'[ApiReportStore.update] API endpoint not yet implemented. ' +
93+
'This method will be activated when user authentication is added.'
94+
);
9895

99-
return response.json();
96+
throw new Error(
97+
'Report updates via API are not yet supported. ' +
98+
'Please ensure you are using localStorage mode.'
99+
);
100100
}
101-
*/
102101

103102
// Not yet implemented, but keeping for future use
104103
/*
@@ -168,25 +167,28 @@ export class LocalStorageReportStore implements UserReportStore {
168167
localStorage.setItem(this.STORAGE_KEY, JSON.stringify(reports));
169168
}
170169

171-
// Not yet implemented, but keeping for future use
172-
/*
173-
async update(userId: string, reportId: string, updates: Partial<UserReport>): Promise<UserReport> {
170+
async update(userReportId: string, updates: Partial<UserReport>): Promise<UserReport> {
174171
const reports = this.getStoredReports();
175-
const index = reports.findIndex(
176-
a => a.userId === userId && a.reportId === reportId
177-
);
172+
173+
// Find by userReport.id (the "sur-" prefixed ID), NOT reportId
174+
const index = reports.findIndex((r) => r.id === userReportId);
178175

179176
if (index === -1) {
180-
throw new Error('Association not found');
177+
throw new Error(`UserReport with id ${userReportId} not found`);
181178
}
182179

183-
const updated = { ...reports[index], ...updates };
180+
// Merge updates and set timestamp
181+
const updated: UserReport = {
182+
...reports[index],
183+
...updates,
184+
updatedAt: new Date().toISOString(),
185+
};
186+
184187
reports[index] = updated;
185188
this.setStoredReports(reports);
186189

187190
return updated;
188191
}
189-
*/
190192

191193
// Not yet implemented, but keeping for future use
192194
/*

0 commit comments

Comments
 (0)