-
Notifications
You must be signed in to change notification settings - Fork 0
1st release #18
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
1st release #18
Changes from all commits
8894742
c535a2b
d31ce20
11f0207
496469e
5af0973
d667fa5
0193222
18a8fd1
a9c736c
498699d
0763c7b
ae442f7
7065193
8b7a905
9bdf819
c777db1
7b41d67
9239757
09bb41c
d39fb9f
baf0acc
9d251f1
99d5c7e
1da8735
9a8362b
2795b7f
65a8f56
4baa0e2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -14,7 +14,8 @@ pids | |
| *.pid | ||
| *.seed | ||
| *.pid.lock | ||
|
|
||
| *.md | ||
| *.txt | ||
|
Comment on lines
+17
to
+18
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Critical: Ignoring all The patterns If you need to ignore specific markdown/text files (e.g., generated reports or local notes), use more specific patterns instead: 🔧 Suggested fix: use specific patterns-*.md
-*.txt
+# Ignore only generated/local documentation
+/docs/generated/*.md
+/reports/*.txt
+notes.md
+TODO.txtOr if these are truly temporary local files, add them to your personal 🤖 Prompt for AI Agents |
||
| # Directory for instrumented libs generated by jscoverage/JSCover | ||
| lib-cov | ||
|
|
||
|
|
||
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,115 @@ | ||
| import { | ||
| S3Client, | ||
| PutObjectCommand, | ||
| GetObjectCommand, | ||
| DeleteObjectCommand, | ||
| DeleteObjectsCommand, | ||
| ListObjectsV2Command, | ||
| type PutObjectCommandInput, | ||
| HeadObjectCommand, | ||
| } from "@aws-sdk/client-s3"; | ||
| import { FolderNameEnum } from "@/config/s3.config"; | ||
|
|
||
| // export enum SecondaryFolderNameEnum { | ||
| // FILES = "files", | ||
| // VIDEOS = "videos", | ||
| // IMAGES = "images", | ||
| // DOCUMENTS = "documents", | ||
| // RECORDINGS = "recordings" | ||
| // } | ||
|
|
||
| export class SecondaryS3Service { | ||
| private s3Client: S3Client; | ||
| private bucketName: string; | ||
|
|
||
| constructor() { | ||
| this.bucketName = process.env.SECONDARY_S3_BUCKET_NAME!; | ||
|
|
||
| this.s3Client = new S3Client({ | ||
| endpoint: process.env.SECONDARY_S3_ENDPOINT!, | ||
| region: process.env.SECONDARY_S3_REGION || 'auto', | ||
| credentials: { | ||
| accessKeyId: process.env.SECONDARY_S3_TOKEN_ID!, | ||
| secretAccessKey: process.env.SECONDARY_S3_SECRET_KEY!, | ||
| }, | ||
| forcePathStyle: true, | ||
| requestHandler: { | ||
| requestTimeout: 300000, // 5 minutes timeout | ||
| } as any, | ||
| }); | ||
| } | ||
|
|
||
| public async listFiles(folder?: FolderNameEnum, maxKeys: number = 1000, continuationToken?: string) { | ||
| const command = new ListObjectsV2Command({ | ||
| Bucket: this.bucketName, | ||
| Prefix: folder ? `${folder}/` : undefined, | ||
| MaxKeys: maxKeys, | ||
| ContinuationToken: continuationToken, | ||
| }); | ||
|
|
||
| const response = await this.s3Client.send(command); | ||
| return { | ||
| files: response.Contents?.map(obj => ({ | ||
| key: obj.Key!, | ||
| size: obj.Size!, | ||
| lastModified: obj.LastModified!, | ||
| etag: obj.ETag!, | ||
| })) || [], | ||
| isTruncated: response.IsTruncated || false, | ||
| nextContinuationToken: response.NextContinuationToken, | ||
| }; | ||
| } | ||
|
|
||
| public async getFile(key: string): Promise<Buffer> { | ||
| const command = new GetObjectCommand({ | ||
| Bucket: this.bucketName, | ||
| Key: key, | ||
| }); | ||
|
|
||
| const response = await this.s3Client.send(command); | ||
|
|
||
| if (!response.Body) { | ||
| throw new Error(`No body returned for key: ${key}`); | ||
| } | ||
|
|
||
| // Convert stream to buffer | ||
| const chunks: Uint8Array[] = []; | ||
| for await (const chunk of response.Body as any) { | ||
| chunks.push(chunk); | ||
| } | ||
| return Buffer.concat(chunks); | ||
| } | ||
|
|
||
| public async getFileStream(key: string) { | ||
| const command = new GetObjectCommand({ | ||
| Bucket: this.bucketName, | ||
| Key: key, | ||
| }); | ||
|
|
||
| const response = await this.s3Client.send(command); | ||
|
|
||
| if (!response.Body) { | ||
| throw new Error(`No body returned for key: ${key}`); | ||
| } | ||
|
|
||
| return response.Body; | ||
| } | ||
|
|
||
| public async getMetadata(key: string) { | ||
| const command = new HeadObjectCommand({ | ||
| Bucket: this.bucketName, | ||
| Key: key, | ||
| }); | ||
| const response = await this.s3Client.send(command); | ||
| return { | ||
| contentType: response.ContentType, | ||
| contentLength: response.ContentLength, | ||
| lastModified: response.LastModified, | ||
| metadata: response.Metadata, | ||
| etag: response.ETag, | ||
| }; | ||
| } | ||
| } | ||
|
|
||
| export default new SecondaryS3Service(); | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift
🧩 Analysis chain
🏁 Script executed:
Repository: venu123143/FileFlowBe
Length of output: 3053
🏁 Script executed:
Repository: venu123143/FileFlowBe
Length of output: 22440
Restore deployment migrations before starting the app.
./migrate.shis only a disabled comment in the deploy step, and the remaining migrations are manual Sequelize CLI commands. If this deploy runs on existing DB state, add a database migration command to the CI server script, or document/verify that this release has no schema or data migrations required before release.🤖 Prompt for AI Agents