Skip to content

Commit 3117b8f

Browse files
authored
Merge pull request #20 from asepindrak/dev
Dev
2 parents cac4f41 + 7a76a95 commit 3117b8f

21 files changed

+1231
-496
lines changed

README.md

Lines changed: 92 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,14 @@ With CommitFlow, you can **plan, track, and analyze your projects** — all in o
1414

1515
---
1616

17+
## ![CommitFlow Preview](./images/commitflow.jpg)
18+
19+
| Chat 1 | Chat 2 |
20+
| ---------------------------------- | ---------------------------------- |
21+
| ![](./images/commitflow-chat1.jpg) | ![](./images/commitflow-chat2.jpg) |
22+
23+
---
24+
1725
## 📁 Folder Structure
1826

1927
```
@@ -31,7 +39,15 @@ With CommitFlow, you can **plan, track, and analyze your projects** — all in o
3139

3240
## ✨ Features
3341

34-
### 🔧 Project Management
42+
### 🤖 AI-Powered Insights
43+
44+
- 💡 **AI Recommendations** – Get automatic suggestions for prioritization and sprint planning.
45+
- 🧠 **Smart Summaries** – Let AI summarize repository activity and project status.
46+
- 🗣️ **Insight Chatbot** – Ask questions like “which tasks are in progress??” or “who contributed the most to the commitflow repo?”
47+
48+
---
49+
50+
### 🧭 Project Management
3551

3652
A beautiful, AI-assisted workspace for managing your projects and tasks:
3753

@@ -45,14 +61,38 @@ A beautiful, AI-assisted workspace for managing your projects and tasks:
4561
- **Inline comments** with author, timestamp, and preview links
4662
- 🎨 **Smart Selectors**
4763
- Assignee and Priority fields powered by **React Select**, dynamically colored per user or priority level
48-
- 🧍 **Team Management**
49-
Add or remove team members using modern UI components, with color-coded avatars automatically generated.
64+
- 🗃️ **Workspace Management**
65+
Add workspace.
5066
- 🧱 **Project Management Sidebar**
5167
- Create or delete projects easily
5268
- Integrated **SweetAlert2** confirmations for safe deletions
69+
- 🧍 **Team Management**
70+
Add or remove team members using modern UI components, with color-coded avatars automatically generated.
5371
- **Toast notifications** (`react-toastify`) for success actions (e.g., project or member added)
5472
- 🌙 **Dark/Light Mode Aware**
5573
Smooth color transitions and well-tuned contrast for both themes.
74+
- Due date labels: **Due Today** & **Overdue**
75+
- Filter **Assigned to Me**
76+
77+
---
78+
79+
### 💬 Team Coordination
80+
81+
- **Follow up tasks via WhatsApp**
82+
- Generates dynamic `wa.me` link (manual click — no API yet)
83+
- Pre-filled message with task title & status
84+
- Real-time collaboration coming soon
85+
- **Follow up tasks via WhatsApp**
86+
- **Automatic email notifications** sent to team members when tasks are updated
87+
- **Invite team members via email** with secure join links
88+
89+
---
90+
91+
### 🔄 Offline‑First Sync
92+
93+
- Works seamlessly **without internet**
94+
- Local storage caching (offline‑first approach)
95+
- Auto‑synchronization when back online
5696

5797
---
5898

@@ -64,19 +104,60 @@ A beautiful, AI-assisted workspace for managing your projects and tasks:
64104

65105
---
66106

67-
### 🤖 AI-Powered Insights
107+
### 🎨 Interactive UI
68108

69-
- 💡 **AI Recommendations** – Get automatic suggestions for prioritization and sprint planning.
70-
- 🧠 **Smart Summaries** – Let AI summarize repository activity and project status.
71-
- 🗣️ **Insight Chatbot** – Ask questions like “Who’s most active this week?” or “Which repo grew fastest?”
109+
- Smooth animations
110+
- Responsive layout
111+
- Clean, minimalist UX with focus on productivity
72112

73113
---
74114

75-
### 🐳 Infrastructure & Security
115+
## 🛠️ Tech Stack
116+
117+
### Frontend
118+
119+
- React + Vite
120+
- TypeScript
121+
- TailwindCSS
122+
- Zustand (State Management)
123+
- LocalStorage / IndexedDB (Offline Sync)
124+
- React Query (Data Fetching & Sync Management)
125+
- Socket.IO Client (Real-time updates)
126+
- React Quill (Rich Text Editor)
127+
- SweetAlert2 (Dialogs)
128+
- React Toastify (Notifications)
129+
- Framer Motion / GSAP (Animations & interactive UI)
130+
- XLSX (Export Excel)
131+
132+
### Backend
133+
134+
- Nest.js
135+
- TypeScript
136+
- Prisma ORM
137+
- PostgreSQL
138+
- Socket.IO Gateway (Real-time events)
139+
- Nodemailer (Email Delivery via SMTP)
140+
- Multer (File upload middleware)
141+
- Class Validator / Class Transformer
142+
- Swagger (API documentation)
143+
- Google TTS API
144+
- AWS SDK for S3 Storage
145+
- JWT Authentication (Access & Refresh Tokens)
146+
- OpenAI API Integration (AI features / content generation)
147+
148+
---
76149

77-
- 🧩 **PostgreSQL Storage** – Store structured task and analytics data.
78-
- 🔐 **Environment Management** – Secure credentials via `.env` file.
79-
- ⚙️ **Docker Ready** – Run everything locally or in production with one command.
150+
## 🐳 Infrastructure & Security (Updated)
151+
152+
- 🗄️ **PostgreSQL Database** – Structured project and task data.
153+
- ☁️ **AWS S3 Storage** – Media & attachments.
154+
- ✉️ **SMTP Email (Nodemailer)** – Invitations & notifications.
155+
- 🔐 **Environment Variables (.env)** – Secure credential management.
156+
- 📡 **WebSocket Gateway** – Realtime updates via Socket.IO.
157+
- 🔑 **JWT Authentication** – Secure login, workspace access, and API protection.
158+
- 🤖 **OpenAI Integration** – AI-driven generation (text, automation, suggestions).
159+
- 📁 **LocalStorage + IndexedDB** – Offline-first data with auto-sync.
160+
- 📘 **Swagger UI** – API documentation.
80161

81162
---
82163

backend/src/ai-agent/ask.service.ts

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ export class AskService {
3636
if (socket) {
3737
socket.emit("ai_thinking", {
3838
type: "tool_call",
39-
message: `🤖 CommitFlow memproses permintaan tool: ${tool}`,
39+
message: `🤖 CommitFlow is processing the tool request: ${tool}`,
4040
tool,
4141
args,
4242
});
@@ -51,7 +51,7 @@ export class AskService {
5151
if (socket) {
5252
socket.emit("ai_thinking", {
5353
type: "tool_result",
54-
message: `📊 Hasil tool ${tool} siap.`,
54+
message: `📊 Tool result for ${tool} is ready.`,
5555
tool,
5656
result,
5757
});
@@ -62,7 +62,7 @@ export class AskService {
6262
if (socket) {
6363
socket.emit("ai_thinking", {
6464
type: "done",
65-
message: `✅ Semua proses selesai.`,
65+
message: `✅ All processes completed.`,
6666
});
6767
}
6868
}
@@ -71,32 +71,32 @@ export class AskService {
7171
* Helper: execute a tool by name (serial)
7272
* Returns the raw tool result (JS object/array) or { error: ... }
7373
*/
74-
private async execToolByName(fn: string, args: any, userId: string) {
74+
private async execToolByName(fn: string, args: any) {
7575
try {
7676
if (fn === "getRepos") {
7777
return await getRepos();
7878
} else if (fn === "getContributors") {
7979
return await getContributors(args.repo);
8080
} else if (fn === "getProjects") {
81-
return await getProjects(userId);
81+
return await getProjects(args.workspaceId);
8282
} else if (fn === "getMembers") {
83-
return await getMembers(userId);
83+
return await getMembers(args.workspaceId);
8484
} else if (fn === "getAllTasks") {
85-
return await getAllTasks(args?.projectId || "", userId);
85+
return await getAllTasks(args?.projectId);
8686
} else if (fn === "getTodoTasks") {
87-
return await getTodoTasks(args?.projectId || "", userId);
87+
return await getTodoTasks(args?.projectId);
8888
} else if (fn === "getInProgressTasks") {
89-
return await getInProgressTasks(args?.projectId || "", userId);
89+
return await getInProgressTasks(args?.projectId);
9090
} else if (fn === "getDoneTasks") {
91-
return await getDoneTasks(args?.projectId || "", userId);
91+
return await getDoneTasks(args?.projectId);
9292
} else if (fn === "getUnassignedTasks") {
93-
return await getUnassignedTasks(args?.projectId || "", userId);
93+
return await getUnassignedTasks(args?.projectId);
9494
} else if (fn === "getUrgentTasks") {
95-
return await getUrgentTasks(args?.projectId || "", userId);
95+
return await getUrgentTasks(args?.projectId);
9696
} else if (fn === "getLowTasks") {
97-
return await getLowTasks(args?.projectId || "", userId);
97+
return await getLowTasks(args?.projectId);
9898
} else if (fn === "getMediumTasks") {
99-
return await getMediumTasks(args?.projectId || "", userId);
99+
return await getMediumTasks(args?.projectId);
100100
} else {
101101
return { error: `Unknown tool: ${fn}` };
102102
}
@@ -132,6 +132,14 @@ export class AskService {
132132
content: SYSTEM_MESSAGE,
133133
},
134134
...userMessages.map((msg) => ({ role: msg.role, content: msg.content })),
135+
{
136+
role: "system",
137+
content: `User Selected Workspace ID: ${data.workspaceId}`,
138+
},
139+
{
140+
role: "system",
141+
content: `User Selected Project ID: ${data.projectId}`,
142+
},
135143
...data.messages,
136144
];
137145

@@ -223,7 +231,7 @@ export class AskService {
223231
} else {
224232
// Execute actual tool
225233
this.emitToolCall(socket, fn, args);
226-
toolResult = await this.execToolByName(fn, args, userId ?? "");
234+
toolResult = await this.execToolByName(fn, args);
227235
this.emitToolResult(socket, fn, toolResult);
228236

229237
// push tool result into conversation
@@ -289,7 +297,7 @@ export class AskService {
289297

290298
messages.push({
291299
role: "system",
292-
content: "buatkan summary dari hasil tools call jika ada",
300+
content: "generate a summary of the tool call results if available",
293301
});
294302
// === At this point, modelMessage does NOT request tools anymore ===
295303
// Start SSE streaming final answer. Ensure we include tools & tool_choice
@@ -379,7 +387,7 @@ export class AskService {
379387
choices: [
380388
{
381389
delta: {
382-
content: `Terjadi kesalahan: ${
390+
content: `An error occurred: ${
383391
error?.message || String(error)
384392
}`,
385393
},

backend/src/ai-agent/messages/messages.controller.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ export class MessagesController {
2222

2323
@Delete(":id")
2424
delete(@Req() req: any, @Param("id") id: string) {
25-
console.log("delete message id: ", id);
2625
const userId = req.user.userId; // <-- ambil userId dari JWT
2726
return this.messagesService.delete(userId, id);
2827
}

0 commit comments

Comments
 (0)