org.springframework.boot
spring-boot-starter-actuator
diff --git a/src/main/frontend/explorer-tailwind.config.ts b/src/main/frontend/explorer-tailwind.config.ts
deleted file mode 100644
index b3fc1b23..00000000
--- a/src/main/frontend/explorer-tailwind.config.ts
+++ /dev/null
@@ -1,57 +0,0 @@
-import type { Config } from 'tailwindcss';
-
-/**
- * Tailwind config for the Thymeleaf explorer UI templates.
- * Separate from the React app config to preserve the original blue brand colors.
- */
-export default {
- darkMode: 'class',
- content: [
- '../resources/templates/**/*.html',
- ],
- theme: {
- extend: {
- colors: {
- brand: {
- 50: '#eff6ff',
- 100: '#dbeafe',
- 200: '#bfdbfe',
- 300: '#93c5fd',
- 400: '#60a5fa',
- 500: '#3b82f6',
- 600: '#2563eb',
- 700: '#1d4ed8',
- 800: '#1e40af',
- 900: '#1e3a5f',
- },
- surface: {
- DEFAULT: '#f8fafc',
- dark: '#0f172a',
- },
- card: {
- DEFAULT: '#ffffff',
- dark: '#1e293b',
- },
- muted: {
- DEFAULT: '#64748b',
- dark: '#94a3b8',
- },
- },
- animation: {
- 'fade-in': 'fadeIn 0.3s ease-out',
- 'slide-up': 'slideUp 0.3s ease-out',
- },
- keyframes: {
- fadeIn: {
- '0%': { opacity: '0' },
- '100%': { opacity: '1' },
- },
- slideUp: {
- '0%': { opacity: '0', transform: 'translateY(8px)' },
- '100%': { opacity: '1', transform: 'translateY(0)' },
- },
- },
- },
- },
- plugins: [],
-} satisfies Config;
diff --git a/src/main/frontend/package.json b/src/main/frontend/package.json
index ade92897..5a61c35e 100644
--- a/src/main/frontend/package.json
+++ b/src/main/frontend/package.json
@@ -5,8 +5,7 @@
"type": "module",
"scripts": {
"dev": "vite",
- "build": "tsc -b && vite build && npm run build:explorer-css",
- "build:explorer-css": "npx tailwindcss -c ./explorer-tailwind.config.ts -i ./src/explorer.css -o ../resources/static/css/explorer.css --minify",
+ "build": "tsc -b && vite build",
"preview": "vite preview"
},
"dependencies": {
diff --git a/src/main/java/io/github/randomcodespace/iq/web/ExplorerController.java b/src/main/java/io/github/randomcodespace/iq/web/ExplorerController.java
deleted file mode 100644
index f6dcfacd..00000000
--- a/src/main/java/io/github/randomcodespace/iq/web/ExplorerController.java
+++ /dev/null
@@ -1,108 +0,0 @@
-package io.github.randomcodespace.iq.web;
-
-import io.github.randomcodespace.iq.query.QueryService;
-import org.springframework.context.annotation.Profile;
-import org.springframework.stereotype.Controller;
-import org.springframework.ui.Model;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestParam;
-
-import java.util.List;
-import java.util.Map;
-
-/**
- * Thymeleaf-based web UI controller for exploring the code knowledge graph.
- * Only active when the "serving" profile is enabled (i.e. during {@code osscodeiq serve}).
- *
- * Full-page routes live under {@code /ui}, HTMX fragment routes under {@code /ui/fragments}.
- */
-@Controller
-@Profile("serving")
-@RequestMapping("/ui")
-@org.springframework.boot.autoconfigure.condition.ConditionalOnProperty(name = "codeiq.neo4j.enabled", havingValue = "true", matchIfMissing = true)
-public class ExplorerController {
-
- private final QueryService queryService;
-
- public ExplorerController(QueryService queryService) {
- this.queryService = queryService;
- }
-
- // ---- Full-page routes ----
-
- @GetMapping({"", "/"})
- public String index(Model model) {
- model.addAttribute("stats", queryService.getStats());
- model.addAttribute("kinds", queryService.listKinds());
- return "explorer/index";
- }
-
- @GetMapping("/kinds/{kind}")
- public String nodesByKind(
- @PathVariable String kind,
- @RequestParam(defaultValue = "50") int limit,
- @RequestParam(defaultValue = "0") int offset,
- Model model) {
- model.addAttribute("result", queryService.nodesByKind(kind, limit, offset));
- model.addAttribute("kind", kind);
- return "explorer/nodes";
- }
-
- @GetMapping("/node")
- public String nodeDetail(@RequestParam String nodeId, Model model) {
- Map detail = queryService.nodeDetailWithEdges(nodeId);
- model.addAttribute("detail", detail);
- return "explorer/detail";
- }
-
- // ---- HTMX fragment routes ----
-
- @GetMapping("/fragments/kinds")
- public String kindsFragment(Model model) {
- model.addAttribute("kinds", queryService.listKinds());
- return "explorer/fragments/kinds-grid";
- }
-
- @GetMapping("/fragments/nodes/{kind}")
- public String nodesFragment(
- @PathVariable String kind,
- @RequestParam(defaultValue = "50") int limit,
- @RequestParam(defaultValue = "0") int offset,
- Model model) {
- model.addAttribute("result", queryService.nodesByKind(kind, limit, offset));
- model.addAttribute("kind", kind);
- return "explorer/fragments/nodes-grid";
- }
-
- @GetMapping("/fragments/detail")
- public String detailFragment(@RequestParam String nodeId, Model model) {
- Map detail = queryService.nodeDetailWithEdges(nodeId);
- model.addAttribute("detail", detail);
- return "explorer/fragments/detail-panel";
- }
-
- @GetMapping("/fragments/search")
- public String searchFragment(
- @RequestParam String q,
- @RequestParam(defaultValue = "50") int limit,
- Model model) {
- List