Files
hack/tools/scripts/llm-key-hunter/results/_cache/content/2321robin_smartstudyassistant.json
T

1 line
32 KiB
JSON

{"repo": "2321robin/smartstudyassistant", "files": {"backend/plan-service/src/main/java/com/smartstudy/plan/service/AiPlanService.java": {"d7e9cd477fd9bc64cc50b17e633403a84e54686a": {"t": 1785745693.3458502, "n": 6832, "h": "41434bf9880351c6", "c": "package com.smartstudy.plan.service;\n\nimport com.fasterxml.jackson.databind.JsonNode;\nimport com.fasterxml.jackson.databind.ObjectMapper;\nimport com.smartstudy.plan.entity.StudyTask;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.beans.factory.annotation.Value;\nimport org.springframework.boot.web.client.RestTemplateBuilder;\nimport org.springframework.http.HttpEntity;\nimport org.springframework.http.HttpHeaders;\nimport org.springframework.http.MediaType;\nimport org.springframework.stereotype.Service;\nimport org.springframework.util.StringUtils;\nimport org.springframework.web.client.RestTemplate;\n\nimport java.time.Duration;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Map;\n\n@Service\npublic class AiPlanService {\n\n private static final String DEFAULT_STATUS = \"PENDING\";\n private static final Logger log = LoggerFactory.getLogger(AiPlanService.class);\n\n private final RestTemplate restTemplate;\n private final ObjectMapper objectMapper;\n private final String apiKey;\n private final String baseUrl;\n private final String model;\n\n @Autowired\n public AiPlanService(\n RestTemplateBuilder restTemplateBuilder,\n ObjectMapper objectMapper,\n @Value(\"${deepseek.api-key:${DEEPSEEK_API_KEY:}}\") String apiKey,\n @Value(\"${deepseek.base-url:https://api.deepseek.com}\") String baseUrl,\n @Value(\"${deepseek.model:deepseek-chat}\") String model) {\n this(\n restTemplateBuilder\n .setConnectTimeout(Duration.ofSeconds(10))\n .setReadTimeout(Duration.ofSeconds(20))\n .build(),\n objectMapper,\n apiKey,\n baseUrl,\n model\n );\n }\n\n AiPlanService(RestTemplateBuilder restTemplateBuilder, String apiKey, String baseUrl, String model) {\n this(\n restTemplateBuilder\n .setConnectTimeout(Duration.ofSeconds(10))\n .setReadTimeout(Duration.ofSeconds(20))\n .build(),\n new ObjectMapper(),\n apiKey,\n baseUrl,\n model\n );\n }\n\n AiPlanService(RestTemplate restTemplate, String apiKey, String baseUrl, String model) {\n this(restTemplate, new ObjectMapper(), apiKey, baseUrl, model);\n }\n\n AiPlanService(RestTemplate restTemplate, ObjectMapper objectMapper, String apiKey, String baseUrl, String model) {\n this.restTemplate = restTemplate;\n this.objectMapper = objectMapper;\n this.apiKey = apiKey;\n this.baseUrl = baseUrl;\n this.model = model;\n }\n\n public List<StudyTask> generateTasks(String goal, Integer durationDays, Integer dailyHours) {\n if (!StringUtils.hasText(apiKey)) {\n return fallbackTasks(\"api key missing\");\n }\n\n try {\n List<StudyTask> aiTasks = requestDeepSeekTasks(goal, durationDays, dailyHours);\n if (aiTasks.isEmpty()) {\n return fallbackTasks(\"deepseek returned no tasks\");\n }\n log.info(\"Plan generation source=deepseek model={} goal={}\", model, goal);\n return aiTasks;\n } catch (Exception exception) {\n return fallbackTasks(\"deepseek request failed: \" + exception.getClass().getSimpleName());\n }\n }\n\n private List<StudyTask> requestDeepSeekTasks(String goal, Integer durationDays, Integer dailyHours) throws Exception {\n HttpHeaders headers = new HttpHeaders();\n headers.setBearerAuth(apiKey);\n headers.setContentType(MediaType.APPLICATION_JSON);\n\n Map<String, Object> requestBody = Map.of(\n \"model\", model,\n \"temperature\", 0.7,\n \"response_format\", Map.of(\"type\", \"json_object\"),\n \"messages\", List.of(\n Map.of(\"role\", \"system\", \"content\", \"你是学习规划助手。请只返回 JSON 对象,不要返回 Markdown,不要解释。\"),\n Map.of(\"role\", \"user\", \"content\", buildPrompt(goal, durationDays, dailyHours))\n )\n );\n\n String requestJson = objectMapper.writeValueAsString(requestBody);\n\n String responseBody = restTemplate.postForObject(\n normalizeBaseUrl(baseUrl) + \"/chat/completions\",\n new HttpEntity<>(requestJson, headers),\n String.class\n );\n\n if (!StringUtils.hasText(responseBody)) {\n return fallbackTasks(\"deepseek response body empty\");\n }\n\n JsonNode root = objectMapper.readTree(responseBody);\n JsonNode contentNode = root.path(\"choices\").path(0).path(\"message\").path(\"content\");\n if (!contentNode.isTextual() || !StringUtils.hasText(contentNode.asText())) {\n return fallbackTasks(\"deepseek content missing\");\n }\n\n JsonNode tasksNode = objectMapper.readTree(contentNode.asText()).path(\"tasks\");\n if (!tasksNode.isArray() || tasksNode.isEmpty()) {\n return fallbackTasks(\"deepseek tasks missing\");\n }\n\n List<StudyTask> tasks = new ArrayList<>();\n for (JsonNode taskNode : tasksNode) {\n String title = taskNode.path(\"title\").asText();\n int stage = taskNode.path(\"stage\").asInt(tasks.size() + 1);\n if (StringUtils.hasText(title)) {\n tasks.add(new StudyTask(null, title.trim(), stage, DEFAULT_STATUS));\n }\n }\n\n return tasks;\n }\n\n private String buildPrompt(String goal, Integer durationDays, Integer dailyHours) {\n return \"\"\"\n 请根据以下学习目标生成一个中文学习计划。\n 只返回 JSON 对象,格式如下:\n {\"tasks\":[{\"title\":\"阶段任务标题\",\"stage\":1},{\"title\":\"阶段任务标题\",\"stage\":2}]}\n\n 要求:\n 1. 返回 4 到 6 个阶段任务\n 2. 任务标题要具体、自然,适合课程项目演示\n 3. stage 从 1 开始递增\n 4. 不要输出除 JSON 以外的任何内容\n\n 学习目标:%s\n 计划天数:%d\n 每日学习时长:%d 小时\n \"\"\".formatted(goal, durationDays, dailyHours);\n }\n\n private String normalizeBaseUrl(String value) {\n if (value.endsWith(\"/\")) {\n return value.substring(0, value.length() - 1);\n }\n return value;\n }\n\n private List<StudyTask> fallbackTasks(String reason) {\n log.info(\"Plan generation source=fallback-template reason={} model={} \", reason, model);\n return List.of(\n new StudyTask(null, \"阶段一:基础准备\", 1, DEFAULT_STATUS),\n new StudyTask(null, \"阶段二:核心学习\", 2, DEFAULT_STATUS),\n new StudyTask(null, \"阶段三:项目实践\", 3, DEFAULT_STATUS),\n new StudyTask(null, \"阶段四:总结复习\", 4, DEFAULT_STATUS)\n );\n }\n}\n"}, "dd3022c596e6d8193ca9cf3fec9676fa81adb7f0": {"t": 1785755736.2267494, "n": 6832, "h": "41434bf9880351c6", "c": "package com.smartstudy.plan.service;\n\nimport com.fasterxml.jackson.databind.JsonNode;\nimport com.fasterxml.jackson.databind.ObjectMapper;\nimport com.smartstudy.plan.entity.StudyTask;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.beans.factory.annotation.Value;\nimport org.springframework.boot.web.client.RestTemplateBuilder;\nimport org.springframework.http.HttpEntity;\nimport org.springframework.http.HttpHeaders;\nimport org.springframework.http.MediaType;\nimport org.springframework.stereotype.Service;\nimport org.springframework.util.StringUtils;\nimport org.springframework.web.client.RestTemplate;\n\nimport java.time.Duration;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Map;\n\n@Service\npublic class AiPlanService {\n\n private static final String DEFAULT_STATUS = \"PENDING\";\n private static final Logger log = LoggerFactory.getLogger(AiPlanService.class);\n\n private final RestTemplate restTemplate;\n private final ObjectMapper objectMapper;\n private final String apiKey;\n private final String baseUrl;\n private final String model;\n\n @Autowired\n public AiPlanService(\n RestTemplateBuilder restTemplateBuilder,\n ObjectMapper objectMapper,\n @Value(\"${deepseek.api-key:${DEEPSEEK_API_KEY:}}\") String apiKey,\n @Value(\"${deepseek.base-url:https://api.deepseek.com}\") String baseUrl,\n @Value(\"${deepseek.model:deepseek-chat}\") String model) {\n this(\n restTemplateBuilder\n .setConnectTimeout(Duration.ofSeconds(10))\n .setReadTimeout(Duration.ofSeconds(20))\n .build(),\n objectMapper,\n apiKey,\n baseUrl,\n model\n );\n }\n\n AiPlanService(RestTemplateBuilder restTemplateBuilder, String apiKey, String baseUrl, String model) {\n this(\n restTemplateBuilder\n .setConnectTimeout(Duration.ofSeconds(10))\n .setReadTimeout(Duration.ofSeconds(20))\n .build(),\n new ObjectMapper(),\n apiKey,\n baseUrl,\n model\n );\n }\n\n AiPlanService(RestTemplate restTemplate, String apiKey, String baseUrl, String model) {\n this(restTemplate, new ObjectMapper(), apiKey, baseUrl, model);\n }\n\n AiPlanService(RestTemplate restTemplate, ObjectMapper objectMapper, String apiKey, String baseUrl, String model) {\n this.restTemplate = restTemplate;\n this.objectMapper = objectMapper;\n this.apiKey = apiKey;\n this.baseUrl = baseUrl;\n this.model = model;\n }\n\n public List<StudyTask> generateTasks(String goal, Integer durationDays, Integer dailyHours) {\n if (!StringUtils.hasText(apiKey)) {\n return fallbackTasks(\"api key missing\");\n }\n\n try {\n List<StudyTask> aiTasks = requestDeepSeekTasks(goal, durationDays, dailyHours);\n if (aiTasks.isEmpty()) {\n return fallbackTasks(\"deepseek returned no tasks\");\n }\n log.info(\"Plan generation source=deepseek model={} goal={}\", model, goal);\n return aiTasks;\n } catch (Exception exception) {\n return fallbackTasks(\"deepseek request failed: \" + exception.getClass().getSimpleName());\n }\n }\n\n private List<StudyTask> requestDeepSeekTasks(String goal, Integer durationDays, Integer dailyHours) throws Exception {\n HttpHeaders headers = new HttpHeaders();\n headers.setBearerAuth(apiKey);\n headers.setContentType(MediaType.APPLICATION_JSON);\n\n Map<String, Object> requestBody = Map.of(\n \"model\", model,\n \"temperature\", 0.7,\n \"response_format\", Map.of(\"type\", \"json_object\"),\n \"messages\", List.of(\n Map.of(\"role\", \"system\", \"content\", \"你是学习规划助手。请只返回 JSON 对象,不要返回 Markdown,不要解释。\"),\n Map.of(\"role\", \"user\", \"content\", buildPrompt(goal, durationDays, dailyHours))\n )\n );\n\n String requestJson = objectMapper.writeValueAsString(requestBody);\n\n String responseBody = restTemplate.postForObject(\n normalizeBaseUrl(baseUrl) + \"/chat/completions\",\n new HttpEntity<>(requestJson, headers),\n String.class\n );\n\n if (!StringUtils.hasText(responseBody)) {\n return fallbackTasks(\"deepseek response body empty\");\n }\n\n JsonNode root = objectMapper.readTree(responseBody);\n JsonNode contentNode = root.path(\"choices\").path(0).path(\"message\").path(\"content\");\n if (!contentNode.isTextual() || !StringUtils.hasText(contentNode.asText())) {\n return fallbackTasks(\"deepseek content missing\");\n }\n\n JsonNode tasksNode = objectMapper.readTree(contentNode.asText()).path(\"tasks\");\n if (!tasksNode.isArray() || tasksNode.isEmpty()) {\n return fallbackTasks(\"deepseek tasks missing\");\n }\n\n List<StudyTask> tasks = new ArrayList<>();\n for (JsonNode taskNode : tasksNode) {\n String title = taskNode.path(\"title\").asText();\n int stage = taskNode.path(\"stage\").asInt(tasks.size() + 1);\n if (StringUtils.hasText(title)) {\n tasks.add(new StudyTask(null, title.trim(), stage, DEFAULT_STATUS));\n }\n }\n\n return tasks;\n }\n\n private String buildPrompt(String goal, Integer durationDays, Integer dailyHours) {\n return \"\"\"\n 请根据以下学习目标生成一个中文学习计划。\n 只返回 JSON 对象,格式如下:\n {\"tasks\":[{\"title\":\"阶段任务标题\",\"stage\":1},{\"title\":\"阶段任务标题\",\"stage\":2}]}\n\n 要求:\n 1. 返回 4 到 6 个阶段任务\n 2. 任务标题要具体、自然,适合课程项目演示\n 3. stage 从 1 开始递增\n 4. 不要输出除 JSON 以外的任何内容\n\n 学习目标:%s\n 计划天数:%d\n 每日学习时长:%d 小时\n \"\"\".formatted(goal, durationDays, dailyHours);\n }\n\n private String normalizeBaseUrl(String value) {\n if (value.endsWith(\"/\")) {\n return value.substring(0, value.length() - 1);\n }\n return value;\n }\n\n private List<StudyTask> fallbackTasks(String reason) {\n log.info(\"Plan generation source=fallback-template reason={} model={} \", reason, model);\n return List.of(\n new StudyTask(null, \"阶段一:基础准备\", 1, DEFAULT_STATUS),\n new StudyTask(null, \"阶段二:核心学习\", 2, DEFAULT_STATUS),\n new StudyTask(null, \"阶段三:项目实践\", 3, DEFAULT_STATUS),\n new StudyTask(null, \"阶段四:总结复习\", 4, DEFAULT_STATUS)\n );\n }\n}\n"}}, "ops/docker-compose-light.yml": {"d7e9cd477fd9bc64cc50b17e633403a84e54686a": {"t": 1785746993.676084, "n": 3441, "h": "bc72aa3f135b42c2", "c": "services:\n gateway-service:\n image: maven:3.9.9-eclipse-temurin-17\n working_dir: /workspace/backend\n command: sh -c \"mvn install -N -DskipTests && mvn -pl common install -DskipTests && mvn -f gateway-service/pom.xml spring-boot:run\"\n environment:\n SMARTSTUDY_JWT_SECRET: ${SMARTSTUDY_JWT_SECRET:-smartstudy-local-demo-secret}\n USER_SERVICE_URI: http://user-service:8081\n PLAN_SERVICE_URI: http://plan-service:8082\n RESOURCE_SERVICE_URI: http://resource-service:8083\n NOTE_SERVICE_URI: http://note-service:8084\n MAVEN_OPTS: -Xmx192m\n volumes:\n - ../backend:/workspace/backend\n - maven-repo:/root/.m2\n ports:\n - \"8080:8080\"\n depends_on:\n - user-service\n - plan-service\n - resource-service\n - note-service\n\n user-service:\n image: maven:3.9.9-eclipse-temurin-17\n working_dir: /workspace/backend\n command: sh -c \"mvn install -N -DskipTests && mvn -pl common install -DskipTests && mvn -f user-service/pom.xml spring-boot:run -Dspring-boot.run.profiles=local -Dspring-boot.run.jvmArguments='-Dserver.port=8081 -Xmx192m'\"\n environment:\n SMARTSTUDY_JWT_SECRET: ${SMARTSTUDY_JWT_SECRET:-smartstudy-local-demo-secret}\n MAVEN_OPTS: -Xmx192m\n volumes:\n - ../backend:/workspace/backend\n - maven-repo:/root/.m2\n - user-local-data:/root/.smartstudyassistant\n ports:\n - \"127.0.0.1:8081:8081\"\n\n plan-service:\n image: maven:3.9.9-eclipse-temurin-17\n working_dir: /workspace/backend\n command: sh -c \"mvn install -N -DskipTests && mvn -pl common install -DskipTests && mvn -f plan-service/pom.xml spring-boot:run -Dspring-boot.run.jvmArguments='-Dserver.port=8082 -Xmx192m'\"\n environment:\n MAVEN_OPTS: -Xmx192m\n SMARTSTUDY_STORAGE_PLAN_FILE: /data/plans.json\n DEEPSEEK_API_KEY: ${DEEPSEEK_API_KEY:-}\n volumes:\n - ../backend:/workspace/backend\n - maven-repo:/root/.m2\n - plan-data:/data\n ports:\n - \"127.0.0.1:8082:8082\"\n\n resource-service:\n image: maven:3.9.9-eclipse-temurin-17\n working_dir: /workspace/backend\n command: sh -c \"mvn install -N -DskipTests && mvn -pl common install -DskipTests && mvn -f resource-service/pom.xml spring-boot:run -Dspring-boot.run.jvmArguments='-Dserver.port=8083 -Xmx160m'\"\n environment:\n MAVEN_OPTS: -Xmx160m\n volumes:\n - ../backend:/workspace/backend\n - maven-repo:/root/.m2\n ports:\n - \"127.0.0.1:8083:8083\"\n\n note-service:\n image: maven:3.9.9-eclipse-temurin-17\n working_dir: /workspace/backend\n command: sh -c \"mvn install -N -DskipTests && mvn -pl common install -DskipTests && mvn -f note-service/pom.xml spring-boot:run -Dspring-boot.run.jvmArguments='-Dserver.port=8084 -Xmx160m'\"\n environment:\n MAVEN_OPTS: -Xmx160m\n SMARTSTUDY_STORAGE_NOTE_FILE: /data/notes.json\n volumes:\n - ../backend:/workspace/backend\n - maven-repo:/root/.m2\n - note-data:/data\n ports:\n - \"127.0.0.1:8084:8084\"\n\n web-client:\n image: node:20-alpine\n working_dir: /workspace/web-client\n command: sh -c \"npm install && npm run dev -- --host 0.0.0.0 --port 4173\"\n environment:\n VITE_PROXY_TARGET: http://gateway-service:8080\n CHOKIDAR_USEPOLLING: \"true\"\n volumes:\n - ../web-client:/workspace/web-client\n ports:\n - \"4173:4173\"\n depends_on:\n - gateway-service\n\nvolumes:\n maven-repo:\n user-local-data:\n plan-data:\n note-data:\n"}, "a2a525b70e19af3d3382b26a785c51535dcf40ff": {"t": 1785755736.2848117, "n": 3291, "h": "f7a8d172974dea60", "c": "services:\n gateway-service:\n image: maven:3.9.9-eclipse-temurin-17\n working_dir: /workspace/backend\n command: sh -c \"mvn -pl common install -DskipTests && mvn -f gateway-service/pom.xml spring-boot:run\"\n environment:\n SMARTSTUDY_JWT_SECRET: ${SMARTSTUDY_JWT_SECRET:-smartstudy-local-demo-secret}\n USER_SERVICE_URI: http://user-service:8081\n PLAN_SERVICE_URI: http://plan-service:8082\n RESOURCE_SERVICE_URI: http://resource-service:8083\n NOTE_SERVICE_URI: http://note-service:8084\n MAVEN_OPTS: -Xmx192m\n volumes:\n - ../backend:/workspace/backend\n - maven-repo:/root/.m2\n ports:\n - \"8080:8080\"\n depends_on:\n - user-service\n - plan-service\n - resource-service\n - note-service\n\n user-service:\n image: maven:3.9.9-eclipse-temurin-17\n working_dir: /workspace/backend\n command: sh -c \"mvn -pl common install -DskipTests && mvn -f user-service/pom.xml spring-boot:run -Dspring-boot.run.profiles=local -Dspring-boot.run.jvmArguments='-Dserver.port=8081 -Xmx192m'\"\n environment:\n SMARTSTUDY_JWT_SECRET: ${SMARTSTUDY_JWT_SECRET:-smartstudy-local-demo-secret}\n MAVEN_OPTS: -Xmx192m\n volumes:\n - ../backend:/workspace/backend\n - maven-repo:/root/.m2\n - user-local-data:/root/.smartstudyassistant\n ports:\n - \"127.0.0.1:8081:8081\"\n\n plan-service:\n image: maven:3.9.9-eclipse-temurin-17\n working_dir: /workspace/backend\n command: sh -c \"mvn -pl common install -DskipTests && mvn -f plan-service/pom.xml spring-boot:run -Dspring-boot.run.jvmArguments='-Dserver.port=8082 -Xmx192m'\"\n environment:\n MAVEN_OPTS: -Xmx192m\n SMARTSTUDY_STORAGE_PLAN_FILE: /data/plans.json\n DEEPSEEK_API_KEY: ${DEEPSEEK_API_KEY:-}\n volumes:\n - ../backend:/workspace/backend\n - maven-repo:/root/.m2\n - plan-data:/data\n ports:\n - \"127.0.0.1:8082:8082\"\n\n resource-service:\n image: maven:3.9.9-eclipse-temurin-17\n working_dir: /workspace/backend\n command: sh -c \"mvn -pl common install -DskipTests && mvn -f resource-service/pom.xml spring-boot:run -Dspring-boot.run.jvmArguments='-Dserver.port=8083 -Xmx160m'\"\n environment:\n MAVEN_OPTS: -Xmx160m\n volumes:\n - ../backend:/workspace/backend\n - maven-repo:/root/.m2\n ports:\n - \"127.0.0.1:8083:8083\"\n\n note-service:\n image: maven:3.9.9-eclipse-temurin-17\n working_dir: /workspace/backend\n command: sh -c \"mvn -pl common install -DskipTests && mvn -f note-service/pom.xml spring-boot:run -Dspring-boot.run.jvmArguments='-Dserver.port=8084 -Xmx160m'\"\n environment:\n MAVEN_OPTS: -Xmx160m\n SMARTSTUDY_STORAGE_NOTE_FILE: /data/notes.json\n volumes:\n - ../backend:/workspace/backend\n - maven-repo:/root/.m2\n - note-data:/data\n ports:\n - \"127.0.0.1:8084:8084\"\n\n web-client:\n image: node:20-alpine\n working_dir: /workspace/web-client\n command: sh -c \"npm install && npm run dev -- --host 0.0.0.0 --port 4173\"\n environment:\n VITE_PROXY_TARGET: http://gateway-service:8080\n CHOKIDAR_USEPOLLING: \"true\"\n volumes:\n - ../web-client:/workspace/web-client\n ports:\n - \"4173:4173\"\n depends_on:\n - gateway-service\n\nvolumes:\n maven-repo:\n user-local-data:\n plan-data:\n note-data:\n"}, "a941ca847e94c67ec426600a64a76a223b23569c": {"t": 1785755737.4747062, "n": 3086, "h": "932c32ef16ba494b", "c": "services:\n gateway-service:\n image: maven:3.9.9-eclipse-temurin-17\n working_dir: /workspace/backend\n command: mvn -pl gateway-service -am compile spring-boot:run\n environment:\n SMARTSTUDY_JWT_SECRET: ${SMARTSTUDY_JWT_SECRET:-smartstudy-local-demo-secret}\n USER_SERVICE_URI: http://user-service:8081\n PLAN_SERVICE_URI: http://plan-service:8082\n RESOURCE_SERVICE_URI: http://resource-service:8083\n NOTE_SERVICE_URI: http://note-service:8084\n MAVEN_OPTS: -Xmx192m\n volumes:\n - ../backend:/workspace/backend\n - maven-repo:/root/.m2\n ports:\n - \"8080:8080\"\n depends_on:\n - user-service\n - plan-service\n - resource-service\n - note-service\n\n user-service:\n image: maven:3.9.9-eclipse-temurin-17\n working_dir: /workspace/backend\n command: mvn -pl user-service -am compile spring-boot:run -Dspring-boot.run.profiles=local -Dspring-boot.run.jvmArguments=\"-Dserver.port=8081 -Xmx192m\"\n environment:\n SMARTSTUDY_JWT_SECRET: ${SMARTSTUDY_JWT_SECRET:-smartstudy-local-demo-secret}\n MAVEN_OPTS: -Xmx192m\n volumes:\n - ../backend:/workspace/backend\n - maven-repo:/root/.m2\n - user-local-data:/root/.smartstudyassistant\n ports:\n - \"127.0.0.1:8081:8081\"\n\n plan-service:\n image: maven:3.9.9-eclipse-temurin-17\n working_dir: /workspace/backend\n command: mvn -pl plan-service -am compile spring-boot:run -Dspring-boot.run.jvmArguments=\"-Dserver.port=8082 -Xmx192m\"\n environment:\n MAVEN_OPTS: -Xmx192m\n SMARTSTUDY_STORAGE_PLAN_FILE: /data/plans.json\n DEEPSEEK_API_KEY: ${DEEPSEEK_API_KEY:-}\n volumes:\n - ../backend:/workspace/backend\n - maven-repo:/root/.m2\n - plan-data:/data\n ports:\n - \"127.0.0.1:8082:8082\"\n\n resource-service:\n image: maven:3.9.9-eclipse-temurin-17\n working_dir: /workspace/backend\n command: mvn -pl resource-service -am compile spring-boot:run -Dspring-boot.run.jvmArguments=\"-Dserver.port=8083 -Xmx160m\"\n environment:\n MAVEN_OPTS: -Xmx160m\n volumes:\n - ../backend:/workspace/backend\n - maven-repo:/root/.m2\n ports:\n - \"127.0.0.1:8083:8083\"\n\n note-service:\n image: maven:3.9.9-eclipse-temurin-17\n working_dir: /workspace/backend\n command: mvn -pl note-service -am compile spring-boot:run -Dspring-boot.run.jvmArguments=\"-Dserver.port=8084 -Xmx160m\"\n environment:\n MAVEN_OPTS: -Xmx160m\n SMARTSTUDY_STORAGE_NOTE_FILE: /data/notes.json\n volumes:\n - ../backend:/workspace/backend\n - maven-repo:/root/.m2\n - note-data:/data\n ports:\n - \"127.0.0.1:8084:8084\"\n\n web-client:\n image: node:20-alpine\n working_dir: /workspace/web-client\n command: sh -c \"npm install && npm run dev -- --host 0.0.0.0 --port 4173\"\n environment:\n VITE_PROXY_TARGET: http://gateway-service:8080\n CHOKIDAR_USEPOLLING: \"true\"\n volumes:\n - ../web-client:/workspace/web-client\n ports:\n - \"4173:4173\"\n depends_on:\n - gateway-service\n\nvolumes:\n maven-repo:\n user-local-data:\n plan-data:\n note-data:\n"}, "0bc63008069ba2067240bf58b8ee9c7c51a3d39e": {"t": 1785755738.6445966, "n": 3061, "h": "797b313aba69c7ac", "c": "services:\n gateway-service:\n image: maven:3.9.9-eclipse-temurin-17\n working_dir: /workspace/backend\n command: mvn -f gateway-service/pom.xml spring-boot:run\n environment:\n SMARTSTUDY_JWT_SECRET: ${SMARTSTUDY_JWT_SECRET:-smartstudy-local-demo-secret}\n USER_SERVICE_URI: http://user-service:8081\n PLAN_SERVICE_URI: http://plan-service:8082\n RESOURCE_SERVICE_URI: http://resource-service:8083\n NOTE_SERVICE_URI: http://note-service:8084\n MAVEN_OPTS: -Xmx192m\n volumes:\n - ../backend:/workspace/backend\n - maven-repo:/root/.m2\n ports:\n - \"8080:8080\"\n depends_on:\n - user-service\n - plan-service\n - resource-service\n - note-service\n\n user-service:\n image: maven:3.9.9-eclipse-temurin-17\n working_dir: /workspace/backend\n command: mvn -f user-service/pom.xml spring-boot:run -Dspring-boot.run.profiles=local -Dspring-boot.run.jvmArguments=\"-Dserver.port=8081 -Xmx192m\"\n environment:\n SMARTSTUDY_JWT_SECRET: ${SMARTSTUDY_JWT_SECRET:-smartstudy-local-demo-secret}\n MAVEN_OPTS: -Xmx192m\n volumes:\n - ../backend:/workspace/backend\n - maven-repo:/root/.m2\n - user-local-data:/root/.smartstudyassistant\n ports:\n - \"127.0.0.1:8081:8081\"\n\n plan-service:\n image: maven:3.9.9-eclipse-temurin-17\n working_dir: /workspace/backend\n command: mvn -f plan-service/pom.xml spring-boot:run -Dspring-boot.run.jvmArguments=\"-Dserver.port=8082 -Xmx192m\"\n environment:\n MAVEN_OPTS: -Xmx192m\n SMARTSTUDY_STORAGE_PLAN_FILE: /data/plans.json\n DEEPSEEK_API_KEY: ${DEEPSEEK_API_KEY:-}\n volumes:\n - ../backend:/workspace/backend\n - maven-repo:/root/.m2\n - plan-data:/data\n ports:\n - \"127.0.0.1:8082:8082\"\n\n resource-service:\n image: maven:3.9.9-eclipse-temurin-17\n working_dir: /workspace/backend\n command: mvn -f resource-service/pom.xml spring-boot:run -Dspring-boot.run.jvmArguments=\"-Dserver.port=8083 -Xmx160m\"\n environment:\n MAVEN_OPTS: -Xmx160m\n volumes:\n - ../backend:/workspace/backend\n - maven-repo:/root/.m2\n ports:\n - \"127.0.0.1:8083:8083\"\n\n note-service:\n image: maven:3.9.9-eclipse-temurin-17\n working_dir: /workspace/backend\n command: mvn -f note-service/pom.xml spring-boot:run -Dspring-boot.run.jvmArguments=\"-Dserver.port=8084 -Xmx160m\"\n environment:\n MAVEN_OPTS: -Xmx160m\n SMARTSTUDY_STORAGE_NOTE_FILE: /data/notes.json\n volumes:\n - ../backend:/workspace/backend\n - maven-repo:/root/.m2\n - note-data:/data\n ports:\n - \"127.0.0.1:8084:8084\"\n\n web-client:\n image: node:20-alpine\n working_dir: /workspace/web-client\n command: sh -c \"npm install && npm run dev -- --host 0.0.0.0 --port 4173\"\n environment:\n VITE_PROXY_TARGET: http://gateway-service:8080\n CHOKIDAR_USEPOLLING: \"true\"\n volumes:\n - ../web-client:/workspace/web-client\n ports:\n - \"4173:4173\"\n depends_on:\n - gateway-service\n\nvolumes:\n maven-repo:\n user-local-data:\n plan-data:\n note-data:\n"}, "4e865c22ff6218a2dd17f62adb7544cf1b8d82ed": {"t": 1785755739.884628, "n": 3046, "h": "7490ff084038a98c", "c": "services:\n gateway-service:\n image: maven:3.9.9-eclipse-temurin-17\n working_dir: /workspace/backend\n command: mvn -pl gateway-service -am spring-boot:run\n environment:\n SMARTSTUDY_JWT_SECRET: ${SMARTSTUDY_JWT_SECRET:-smartstudy-local-demo-secret}\n USER_SERVICE_URI: http://user-service:8081\n PLAN_SERVICE_URI: http://plan-service:8082\n RESOURCE_SERVICE_URI: http://resource-service:8083\n NOTE_SERVICE_URI: http://note-service:8084\n MAVEN_OPTS: -Xmx192m\n volumes:\n - ../backend:/workspace/backend\n - maven-repo:/root/.m2\n ports:\n - \"8080:8080\"\n depends_on:\n - user-service\n - plan-service\n - resource-service\n - note-service\n\n user-service:\n image: maven:3.9.9-eclipse-temurin-17\n working_dir: /workspace/backend\n command: mvn -pl user-service -am spring-boot:run -Dspring-boot.run.profiles=local -Dspring-boot.run.jvmArguments=\"-Dserver.port=8081 -Xmx192m\"\n environment:\n SMARTSTUDY_JWT_SECRET: ${SMARTSTUDY_JWT_SECRET:-smartstudy-local-demo-secret}\n MAVEN_OPTS: -Xmx192m\n volumes:\n - ../backend:/workspace/backend\n - maven-repo:/root/.m2\n - user-local-data:/root/.smartstudyassistant\n ports:\n - \"127.0.0.1:8081:8081\"\n\n plan-service:\n image: maven:3.9.9-eclipse-temurin-17\n working_dir: /workspace/backend\n command: mvn -pl plan-service -am spring-boot:run -Dspring-boot.run.jvmArguments=\"-Dserver.port=8082 -Xmx192m\"\n environment:\n MAVEN_OPTS: -Xmx192m\n SMARTSTUDY_STORAGE_PLAN_FILE: /data/plans.json\n DEEPSEEK_API_KEY: ${DEEPSEEK_API_KEY:-}\n volumes:\n - ../backend:/workspace/backend\n - maven-repo:/root/.m2\n - plan-data:/data\n ports:\n - \"127.0.0.1:8082:8082\"\n\n resource-service:\n image: maven:3.9.9-eclipse-temurin-17\n working_dir: /workspace/backend\n command: mvn -pl resource-service -am spring-boot:run -Dspring-boot.run.jvmArguments=\"-Dserver.port=8083 -Xmx160m\"\n environment:\n MAVEN_OPTS: -Xmx160m\n volumes:\n - ../backend:/workspace/backend\n - maven-repo:/root/.m2\n ports:\n - \"127.0.0.1:8083:8083\"\n\n note-service:\n image: maven:3.9.9-eclipse-temurin-17\n working_dir: /workspace/backend\n command: mvn -pl note-service -am spring-boot:run -Dspring-boot.run.jvmArguments=\"-Dserver.port=8084 -Xmx160m\"\n environment:\n MAVEN_OPTS: -Xmx160m\n SMARTSTUDY_STORAGE_NOTE_FILE: /data/notes.json\n volumes:\n - ../backend:/workspace/backend\n - maven-repo:/root/.m2\n - note-data:/data\n ports:\n - \"127.0.0.1:8084:8084\"\n\n web-client:\n image: node:20-alpine\n working_dir: /workspace/web-client\n command: sh -c \"npm install && npm run dev -- --host 0.0.0.0 --port 4173\"\n environment:\n VITE_PROXY_TARGET: http://gateway-service:8080\n CHOKIDAR_USEPOLLING: \"true\"\n volumes:\n - ../web-client:/workspace/web-client\n ports:\n - \"4173:4173\"\n depends_on:\n - gateway-service\n\nvolumes:\n maven-repo:\n user-local-data:\n plan-data:\n note-data:\n"}}}}