-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add option to use S3 for reports and results (#21)
* feat: add option to use S3 for reports and results * chore: apply prettier * fix: apply sorting list to api route to work with s3 as well * chore: resolve package lock conflict * fix: report trend sorting after merge * chore: move pw out of storage * fix: build issues due to incorrect package import for trends components * chore: lockfile missing next/swc deps * fix: imports in report page components after merge * feat: clarify readme, describe storage options * fix: prettier ci check
- Loading branch information
Oleksandr Shevtsov
authored
Sep 26, 2024
1 parent
deee4e4
commit ac5772a
Showing
38 changed files
with
2,478 additions
and
2,447 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,14 @@ | ||
import { getServerDataInfo } from '@/app/lib/data'; | ||
import { storage } from '@/app/lib/storage'; | ||
import { withError } from '@/app/lib/withError'; | ||
|
||
export const dynamic = 'force-dynamic'; // defaults to auto | ||
|
||
export async function GET() { | ||
return Response.json(await getServerDataInfo()); | ||
const { result, error } = await withError(storage.getServerDataInfo()); | ||
|
||
if (error) { | ||
return Response.json({ error: error.message }, { status: 500 }); | ||
} | ||
|
||
return Response.json(result); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,17 +1,22 @@ | ||
import { deleteReports } from '@/app/lib/data'; | ||
import { storage } from '@/app/lib/storage'; | ||
import { withError } from '@/app/lib/withError'; | ||
|
||
export const dynamic = 'force-dynamic'; // defaults to auto | ||
export async function DELETE(request: Request) { | ||
const reqData = await request.json(); | ||
const { result: reqData, error: reqError } = await withError(request.json()); | ||
|
||
try { | ||
await deleteReports(reqData.reportsIds); | ||
if (reqError) { | ||
return new Response(reqError.message, { status: 400 }); | ||
} | ||
|
||
const { error } = await withError(storage.deleteReports(reqData.reportsIds)); | ||
|
||
return Response.json({ | ||
message: `Reports deleted successfully`, | ||
reportsIds: reqData.reportsIds, | ||
}); | ||
} catch (err) { | ||
return new Response((err as Error).message, { status: 404 }); | ||
if (error) { | ||
return new Response(error.message, { status: 404 }); | ||
} | ||
|
||
return Response.json({ | ||
message: `Reports deleted successfully`, | ||
reportsIds: reqData.reportsIds, | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,15 @@ | ||
import { readReports } from '@/app/lib/data'; | ||
import { sortReportsByCreatedDate } from '@/app/lib/sort'; | ||
import { storage } from '@/app/lib/storage'; | ||
import { withError } from '@/app/lib/withError'; | ||
|
||
export const dynamic = 'force-dynamic'; // defaults to auto | ||
|
||
export async function GET() { | ||
const reports = await readReports(); | ||
const { result: reports, error } = await withError(storage.readReports()); | ||
|
||
return Response.json(reports); | ||
if (error) { | ||
return new Response(error.message, { status: 400 }); | ||
} | ||
|
||
return Response.json(sortReportsByCreatedDate(reports!)); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,19 +1,23 @@ | ||
import { deleteResults } from '@/app/lib/data'; | ||
import { storage } from '@/app/lib/storage'; | ||
import { withError } from '@/app/lib/withError'; | ||
|
||
export const dynamic = 'force-dynamic'; // defaults to auto | ||
|
||
export async function DELETE(request: Request) { | ||
const reqData = await request.json(); | ||
const { result: reqData, error: reqError } = await withError(request.json()); | ||
|
||
reqData.resultsIds; | ||
try { | ||
await deleteResults(reqData.resultsIds); | ||
if (reqError) { | ||
return new Response(reqError.message, { status: 400 }); | ||
} | ||
|
||
const { error } = await withError(storage.deleteResults(reqData.resultsIds)); | ||
|
||
return Response.json({ | ||
message: `Results files deleted successfully`, | ||
resultsIds: reqData.resultsIds, | ||
}); | ||
} catch (err) { | ||
return new Response((err as Error).message, { status: 404 }); | ||
if (error) { | ||
return new Response(error.message, { status: 404 }); | ||
} | ||
|
||
return Response.json({ | ||
message: `Results files deleted successfully`, | ||
resultsIds: reqData.resultsIds, | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,14 @@ | ||
import { readResults } from '@/app/lib/data'; | ||
import { storage } from '@/app/lib/storage'; | ||
import { withError } from '@/app/lib/withError'; | ||
|
||
export const dynamic = 'force-dynamic'; // defaults to auto | ||
|
||
export async function GET() { | ||
const results = await readResults(); | ||
const { result: results, error } = await withError(storage.readResults()); | ||
|
||
return Response.json(results); | ||
if (error) { | ||
return new Response(error.message, { status: 400 }); | ||
} | ||
|
||
return Response.json(results?.sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime())); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,39 +1,51 @@ | ||
import { saveResult } from '@/app/lib/data'; | ||
import { type ResultDetails, storage } from '@/app/lib/storage'; | ||
import { withError } from '@/app/lib/withError'; | ||
|
||
export const dynamic = 'force-dynamic'; // defaults to auto | ||
export async function PUT(request: Request) { | ||
try { | ||
const formData = await request.formData(); | ||
const { result: formData, error: formParseError } = await withError(request.formData()); | ||
|
||
if (!formData.has('file')) { | ||
return Response.json({ error: 'Field "file" with result is missing' }, { status: 400 }); | ||
} | ||
const file = formData.get('file') as File; | ||
const buffer = Buffer.from(await file.arrayBuffer()); | ||
const resultDetails: { [key: string]: string } = {}; | ||
|
||
for (const [key, value] of formData.entries()) { | ||
if (key === 'file') { | ||
// already processed | ||
continue; | ||
} | ||
// String values for now | ||
resultDetails[key] = value.toString(); | ||
if (formParseError) { | ||
return Response.json({ error: formParseError.message }, { status: 400 }); | ||
} | ||
|
||
if (!formData) { | ||
return Response.json({ error: 'Form data is missing' }, { status: 400 }); | ||
} | ||
|
||
if (!formData.has('file')) { | ||
return Response.json({ error: 'Field "file" with result is missing' }, { status: 400 }); | ||
} | ||
|
||
const file = formData.get('file') as File; | ||
|
||
const { result: arrayBuffer, error: arrayBufferError } = await withError(file.arrayBuffer()); | ||
|
||
if (arrayBufferError) { | ||
return Response.json({ error: `failed to get array buffer: ${arrayBufferError.message}` }, { status: 400 }); | ||
} | ||
|
||
const buffer = Buffer.from(arrayBuffer!); | ||
const resultDetails: ResultDetails = {}; | ||
|
||
for (const [key, value] of formData.entries()) { | ||
if (key === 'file') { | ||
// already processed | ||
continue; | ||
} | ||
const savedResult = await saveResult(buffer, resultDetails); | ||
|
||
return Response.json({ | ||
message: 'Success', | ||
data: savedResult, | ||
status: 201, | ||
}); | ||
} catch (error) { | ||
return Response.json({ | ||
message: 'Failed', | ||
data: { | ||
error: (error as Error).message, | ||
}, | ||
status: 500, | ||
}); | ||
// String values for now | ||
resultDetails[key] = value.toString(); | ||
} | ||
|
||
const { result: savedResult, error } = await withError(storage.saveResult(buffer, resultDetails)); | ||
|
||
if (error) { | ||
return Response.json({ error: `failed to save results: ${error.message}` }, { status: 500 }); | ||
} | ||
|
||
return Response.json({ | ||
message: 'Success', | ||
data: savedResult, | ||
status: 201, | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.