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 ## License
For open source projects, say how it is licensed. For open source projects, say how it is licensed.
---
## Sprint 4 Secure API Key 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.
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
---
+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");
});
}
}