Compare commits

..

22 Commits

Author SHA1 Message Date
Aarthi Manivannan, Premanathan Aarthi Manivannan c00640c15d Update file meeting_report_prompt.txt 2025-12-14 11:52:21 +01:00
Aarthi Manivannan, Premanathan Aarthi Manivannan d80941ca65 Delete .gitkeep 2025-12-14 11:45:47 +01:00
Aarthi Manivannan, Premanathan Aarthi Manivannan 0e4147e893 Delete meeting_report_template.md 2025-12-14 11:45:38 +01:00
Aarthi Manivannan, Premanathan Aarthi Manivannan 9ab69b4b36 Delete .gitkeep 2025-12-14 11:44:59 +01:00
Aarthi Manivannan, Premanathan Aarthi Manivannan cd61d8e09b Delete transcript.txt 2025-12-14 11:44:51 +01:00
Aarthi Manivannan, Premanathan Aarthi Manivannan 893546d142 Delete Example_output.pdf.pdf 2025-12-14 11:44:41 +01:00
Aarthi Manivannan, Premanathan Aarthi Manivannan 9098dafbd5 Delete .gitkeep 2025-12-14 11:44:16 +01:00
Aarthi Manivannan, Premanathan Aarthi Manivannan d68192de8a Delete meeting_report_prompt.txt 2025-12-14 11:44:06 +01:00
Aarthi Manivannan, Premanathan Aarthi Manivannan 5a23ec9c2f Delete .gitkeep 2025-12-14 11:43:24 +01:00
Aarthi Manivannan, Premanathan Aarthi Manivannan a0237ade55 Delete meeting_report_structure.json 2025-12-14 11:39:09 +01:00
Aarthi Manivannan, Premanathan Aarthi Manivannan 10e3c902c5 Delete meeting_report_best_practices.md 2025-12-14 11:37:32 +01:00
Aarthi Manivannan, Premanathan Aarthi Manivannan b157a90671 Upload New File 2025-11-20 12:24:46 +01:00
Aarthi Manivannan, Premanathan Aarthi Manivannan 6931df22e0 Add new file 2025-11-20 12:12:42 +01:00
Aarthi Manivannan, Premanathan Aarthi Manivannan 9eaabe80b6 Add new directory 2025-11-20 12:09:35 +01:00
Aarthi Manivannan, Premanathan Aarthi Manivannan db2192dc30 Add new file 2025-11-20 12:02:32 +01:00
Aarthi Manivannan, Premanathan Aarthi Manivannan 76129982c3 Update file meeting_report_prompt.txt 2025-11-20 11:59:16 +01:00
Aarthi Manivannan, Premanathan Aarthi Manivannan ea769d3aec Add new file 2025-11-20 11:41:14 +01:00
Aarthi Manivannan, Premanathan Aarthi Manivannan 21f4fe95d7 Add new file 2025-11-20 11:38:32 +01:00
Aarthi Manivannan, Premanathan Aarthi Manivannan 8e07bcf028 Add new file 2025-11-20 11:35:47 +01:00
Aarthi Manivannan, Premanathan Aarthi Manivannan fd0798872a Add new directory 2025-11-20 11:32:46 +01:00
Aarthi Manivannan, Premanathan Aarthi Manivannan 0ea3fba436 Add new directory 2025-11-20 11:32:20 +01:00
Aarthi Manivannan, Premanathan Aarthi Manivannan 5615f7fd25 research and design 2025-11-20 11:29:33 +01:00
7 changed files with 111 additions and 179 deletions
+2 -23
View File
@@ -88,27 +88,6 @@ Show your appreciation to those who have contributed to the project.
## License
For open source projects, say how it is licensed.
---
## Sprint 4 Secure API Key Management
In Sprint 4, secure handling of API keys was implemented for the V2D (Video to Document) framework.
### Implementation Overview
- API keys are **not stored in the source code**
- The backend loads the key from an **environment variable**
- A single configuration works for all users without manual setup
- Secrets are protected from being exposed in the repository or frontend
### Configuration
The backend expects the following environment variable:
This variable is injected at runtime by the deployment or CI/CD environment and referenced in `application.yml`.
### Security Benefits
- Prevents accidental exposure of API keys
- Ensures secure collaboration in GitLab
- Follows best practices for secret management
---
## Project status
If you have run out of energy or time for your project, put a note at the top of the README saying that development has slowed down or stopped completely. Someone may choose to fork your project or volunteer to step in as a maintainer or owner, allowing your project to keep going. You can also make an explicit request for maintainers.
+109
View File
@@ -0,0 +1,109 @@
Generate a structured meeting report in MARKDOWN using STRUCTURE and STYLE.
Output ONLY the final .md document — no meta comments, no explanations.
Follow exactly the STRUCTURE defined below.
Follow exactly the STYLE rules.
Use timestamps in HH:MM:SS format.
If information is missing, use: UNKLAR:<reason>.
==================== STRUCTURE & RULES ====================
{
"FORMAT": "markdown",
"STRUCTURE": {
"titlepage": [
"title",
"date",
"start",
"end",
"duration",
"location",
"host",
"participants"
],
"toc": "[section](#anchor) — HH:MM:SS",
"section": {
"h2": "<topic> — HH:MM:SS",
"summary": "exactly 1 concise sentence",
"key_points": "maximum 5 bullet points; quotes optional",
"decisions": "list items formatted as: decision text | owner | due date",
"actions": "markdown table: id | task | owner | due | status"
},
"exec_summary": "exactly 3 short sentences",
"consolidated": [
"decisions",
"actions"
],
"appendix": "optional"
},
"STYLE": {
"tone": "neutral, concise, professional",
"ts_format": "HH:MM:SS",
"no_meta": true
},
"PROCESS": {
"timestamps": "use transcript timestamps if present; otherwise estimate minimal",
"speakers": "use names if available; else Speaker X",
"long_transcripts": "split → summarize → merge",
"unclear": "UNKLAR:<reason>"
},
"PROMPT_SNIPPET": "Generate meeting report in markdown using STRUCTURE and STYLE. Output only the report."
}
============================================================
Insert all generated content into the following MARKDOWN TEMPLATE:
# {{title}}
**Date:** {{date}}
**Start:** {{start}}
**End:** {{end}}
**Duration:** {{duration}}
**Location:** {{location}}
**Host:** {{host}}
**Participants:** {{participants}}
---
## Table of Contents
{{toc}}
---
## Executive Summary
{{exec_summary}}
---
## Sections
{{sections}}
---
## Consolidated Decisions
{{consolidated_decisions}}
---
## Consolidated Actions
{{consolidated_actions}}
---
## Appendix
{{appendix}}
============================================================
Final Requirement:
Output ONLY the completed Markdown meeting report.
-7
View File
@@ -1,7 +0,0 @@
spring:
application:
name: v2d-document
app:
external:
apiKey: ${LLM_API_KEY:}
-13
View File
@@ -1,13 +0,0 @@
package com.v2d.document.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
@Configuration
@ConfigurationProperties(prefix = "app.external")
public class AppProperties {
private String apiKey;
public String getApiKey() { return apiKey; }
public void setApiKey(String apiKey) { this.apiKey = apiKey; }
}
@@ -1,26 +0,0 @@
package com.v2d.document.controller;
import com.v2d.document.service.ExternalApiService;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.Map;
@RestController
@RequestMapping("/api/generate")
public class GenerateController {
private final ExternalApiService externalApiService;
public GenerateController(ExternalApiService externalApiService) {
this.externalApiService = externalApiService;
}
@PostMapping
public ResponseEntity<String> generate(@RequestBody Map<String,Object> body) {
// Build provider payload from the user's body (transform safely)
String payload = "{\"text\": \"use this text\"}"; // adapt for real usage
String providerResponse = externalApiService.callProvider(payload);
return ResponseEntity.ok(providerResponse);
}
}
-90
View File
@@ -1,90 +0,0 @@
package com.v2d.document.service;
import com.v2d.document.config.AppProperties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
@Service
public class ExternalApiService {
private final Logger log = LoggerFactory.getLogger(ExternalApiService.class);
private final AppProperties props;
private final HttpClient http = HttpClient.newHttpClient();
public ExternalApiService(AppProperties props) {
this.props = props;
}
public String callProvider(String jsonPayload) {
String key = props.getApiKey();
if (key == null || key.isBlank()) {
log.warn("External API key is not configured.");
throw new IllegalStateException("External API key missing");
}
try {
HttpRequest req = HttpRequest.newBuilder()
.uri(URI.create("https://api.example.com/endpoint")) // replace with real endpoint
.header("Authorization", "Bearer " + key)
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(jsonPayload))
.build();
HttpResponse<String> resp = http.send(req, HttpResponse.BodyHandlers.ofString());
return resp.body();
} catch (Exception e) {
log.error("External API call failed: {}", e.getMessage());
throw new RuntimeException("External API call failed", e);
}
}
}
package com.v2d.document.service;
import com.v2d.document.config.AppProperties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
@Service
public class ExternalApiService {
private final Logger log = LoggerFactory.getLogger(ExternalApiService.class);
private final AppProperties props;
private final HttpClient http = HttpClient.newHttpClient();
public ExternalApiService(AppProperties props) {
this.props = props;
}
public String callProvider(String jsonPayload) {
String key = props.getApiKey();
if (key == null || key.isBlank()) {
log.warn("External API key is not configured.");
throw new IllegalStateException("External API key missing");
}
try {
HttpRequest req = HttpRequest.newBuilder()
.uri(URI.create("https://api.example.com/endpoint")) // replace with real endpoint
.header("Authorization", "Bearer " + key)
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(jsonPayload))
.build();
HttpResponse<String> resp = http.send(req, HttpResponse.BodyHandlers.ofString());
return resp.body();
} catch (Exception e) {
log.error("External API call failed: {}", e.getMessage());
throw new RuntimeException("External API call failed", e);
}
}
}
-20
View File
@@ -1,20 +0,0 @@
package com.v2d.document.config;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import static org.assertj.core.api.Assertions.assertThat;
public class AppPropertiesTest {
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withUserConfiguration(AppProperties.class)
.withPropertyValues("app.external.apiKey=TEST_KEY");
@Test
void bindsApiKey() {
contextRunner.run(context -> {
AppProperties props = context.getBean(AppProperties.class);
assertThat(props.getApiKey()).isEqualTo("TEST_KEY");
});
}
}