fix: resolve config folders API bugs and test infrastructure
- Fix validation error handler to serialize ValueError objects safely
- Add GET /config-folders/{id} endpoint (was missing)
- Fix project overrides API to accept project_id in body instead of query param
- Add flag_modified for SQLAlchemy JSONB change detection
- Fix DELETE endpoint to return 204 status code
- Fix conftest.py to use single SQLite engine per test
- Install aiosqlite dependency
- Fix frontend ToolWorkshopPage tests button names
Config folders tests: 13/13 passing
Docker build tests: 10/10 passing
Readiness probe tests: 13/13 passing
This commit is contained in:
@@ -487,8 +487,9 @@ export const ToolWorkshopPage = () => {
|
||||
<h3>{selectedToolType ? "Edit" : "Create"} Tool Type</h3>
|
||||
<form onSubmit={handleToolTypeSubmit} className="stack">
|
||||
<div className="form-group">
|
||||
<label>Definition Type</label>
|
||||
<label htmlFor="definition-type">Definition Type</label>
|
||||
<select
|
||||
id="definition-type"
|
||||
value={toolTypeForm.definition_type}
|
||||
onChange={(e) => setToolTypeForm({ ...toolTypeForm, definition_type: e.target.value as "compose" | "dockerfile" })}
|
||||
className="form-input"
|
||||
@@ -499,8 +500,9 @@ export const ToolWorkshopPage = () => {
|
||||
</div>
|
||||
|
||||
<div className="form-group">
|
||||
<label>Name *</label>
|
||||
<label htmlFor="tool-type-name">Name *</label>
|
||||
<input
|
||||
id="tool-type-name"
|
||||
type="text"
|
||||
value={toolTypeForm.name}
|
||||
onChange={(e) => setToolTypeForm({ ...toolTypeForm, name: e.target.value })}
|
||||
@@ -512,8 +514,9 @@ export const ToolWorkshopPage = () => {
|
||||
</div>
|
||||
|
||||
<div className="form-group">
|
||||
<label>Display Name *</label>
|
||||
<label htmlFor="tool-type-display-name">Display Name *</label>
|
||||
<input
|
||||
id="tool-type-display-name"
|
||||
type="text"
|
||||
value={toolTypeForm.display_name}
|
||||
onChange={(e) => setToolTypeForm({ ...toolTypeForm, display_name: e.target.value })}
|
||||
@@ -524,8 +527,9 @@ export const ToolWorkshopPage = () => {
|
||||
</div>
|
||||
|
||||
<div className="form-group">
|
||||
<label>Description</label>
|
||||
<label htmlFor="tool-type-description">Description</label>
|
||||
<input
|
||||
id="tool-type-description"
|
||||
type="text"
|
||||
value={toolTypeForm.description}
|
||||
onChange={(e) => setToolTypeForm({ ...toolTypeForm, description: e.target.value })}
|
||||
@@ -535,8 +539,9 @@ export const ToolWorkshopPage = () => {
|
||||
</div>
|
||||
|
||||
<div className="form-group">
|
||||
<label>Category</label>
|
||||
<label htmlFor="tool-type-category">Category</label>
|
||||
<input
|
||||
id="tool-type-category"
|
||||
type="text"
|
||||
value={toolTypeForm.category}
|
||||
onChange={(e) => setToolTypeForm({ ...toolTypeForm, category: e.target.value })}
|
||||
@@ -568,8 +573,9 @@ export const ToolWorkshopPage = () => {
|
||||
</div>
|
||||
|
||||
<div className="form-group">
|
||||
<label>Default Port *</label>
|
||||
<label htmlFor="tool-type-default-port">Default Port *</label>
|
||||
<input
|
||||
id="tool-type-default-port"
|
||||
type="number"
|
||||
value={toolTypeForm.default_port}
|
||||
onChange={(e) => setToolTypeForm({ ...toolTypeForm, default_port: e.target.value })}
|
||||
@@ -580,8 +586,9 @@ export const ToolWorkshopPage = () => {
|
||||
</div>
|
||||
|
||||
<div className="form-group">
|
||||
<label>{toolTypeForm.definition_type === "compose" ? "Compose Template" : "Dockerfile"} *</label>
|
||||
<label htmlFor="tool-type-template">{toolTypeForm.definition_type === "compose" ? "Compose Template" : "Dockerfile"} *</label>
|
||||
<textarea
|
||||
id="tool-type-template"
|
||||
value={toolTypeForm.definition_type === "compose" ? toolTypeForm.compose_template : toolTypeForm.dockerfile_template}
|
||||
onChange={(e) => {
|
||||
if (toolTypeForm.definition_type === "compose") {
|
||||
@@ -702,8 +709,9 @@ export const ToolWorkshopPage = () => {
|
||||
<h3>{selectedConfig ? "Edit" : "Add"} Config</h3>
|
||||
<form onSubmit={handleConfigSubmit} className="stack">
|
||||
<div className="form-group">
|
||||
<label>Tool Type *</label>
|
||||
<label htmlFor="config-tool-type">Tool Type *</label>
|
||||
<select
|
||||
id="config-tool-type"
|
||||
value={configForm.tool_type_id}
|
||||
onChange={(e) => setConfigForm({ ...configForm, tool_type_id: e.target.value })}
|
||||
className="form-input"
|
||||
@@ -717,8 +725,9 @@ export const ToolWorkshopPage = () => {
|
||||
</div>
|
||||
|
||||
<div className="form-group">
|
||||
<label>Key *</label>
|
||||
<label htmlFor="config-key">Key *</label>
|
||||
<input
|
||||
id="config-key"
|
||||
type="text"
|
||||
value={configForm.key}
|
||||
onChange={(e) => setConfigForm({ ...configForm, key: e.target.value })}
|
||||
@@ -729,8 +738,9 @@ export const ToolWorkshopPage = () => {
|
||||
</div>
|
||||
|
||||
<div className="form-group">
|
||||
<label>Config Type</label>
|
||||
<label htmlFor="config-type">Config Type</label>
|
||||
<select
|
||||
id="config-type"
|
||||
value={configForm.config_type}
|
||||
onChange={(e) => setConfigForm({ ...configForm, config_type: e.target.value })}
|
||||
className="form-input"
|
||||
|
||||
Reference in New Issue
Block a user