Add tags prominence and SIM source grouping features

Database changes:
- Add sim_source_id column to artifacts table for grouping multiple artifacts
- Create Alembic migration (001_add_sim_source_id) for schema update
- Add Alembic env.py for migration support with environment-based DB URLs

API enhancements:
- Add sim_source_id parameter to upload endpoint
- Add sim_source_id filter to query endpoint
- Add new /grouped-by-sim-source endpoint for getting artifacts by group
- Update all API documentation to include sim_source_id

UI improvements:
- Make tags required field and more prominent in upload form
- Add tags display directly in artifacts table (below filename)
- Add SIM Source ID field in upload form with helper text for grouping
- Update table to show sim_source_id (falls back to test_suite if null)
- Tags now displayed as inline badges in main table view

Seed data updates:
- Generate sim_source_id for 70% of artifacts to demonstrate grouping
- Multiple artifacts can share same sim_source_id
- Improved seed data variety with tag combinations

Features:
- Tags are now prominently displayed in both table and detail views
- Multiple artifacts can be grouped by SIM source ID
- Users can filter/query by sim_source_id
- Backward compatible - existing artifacts without sim_source_id still work

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-10-15 09:30:25 -05:00
parent 6eab60987e
commit 21347d8c65
7 changed files with 140 additions and 11 deletions

View File

@@ -109,6 +109,18 @@
</div>
</div>
<div class="form-row">
<div class="form-group">
<label for="sim-source-id">SIM Source ID (for grouping)</label>
<input type="text" id="sim-source-id" name="sim_source_id" placeholder="e.g., sim_run_20251015_001">
<small>Use same ID for multiple artifacts from same source</small>
</div>
<div class="form-group">
<label for="tags">Tags (comma-separated) *</label>
<input type="text" id="tags" name="tags" placeholder="e.g., regression, smoke, critical" required>
</div>
</div>
<div class="form-row">
<div class="form-group">
<label for="test-result">Test Result</label>
@@ -126,11 +138,6 @@
</div>
</div>
<div class="form-group">
<label for="tags">Tags (comma-separated)</label>
<input type="text" id="tags" name="tags" placeholder="e.g., regression, smoke, critical">
</div>
<div class="form-group">
<label for="description">Description</label>
<textarea id="description" name="description" rows="3" placeholder="Describe this artifact..."></textarea>

View File

@@ -73,11 +73,12 @@ function displayArtifacts(artifacts) {
tbody.innerHTML = displayedArtifacts.map(artifact => `
<tr>
<td>${artifact.test_suite || '-'}</td>
<td>${artifact.sim_source_id || artifact.test_suite || '-'}</td>
<td>
<a href="#" onclick="showDetail(${artifact.id}); return false;" style="color: #60a5fa; text-decoration: none;">
${escapeHtml(artifact.filename)}
</a>
${artifact.tags && artifact.tags.length > 0 ? `<br><div style="margin-top: 5px;">${formatTags(artifact.tags)}</div>` : ''}
</td>
<td>${formatDate(artifact.created_at)}</td>
<td>${artifact.test_name || '-'}</td>
@@ -289,9 +290,9 @@ async function uploadArtifact(event) {
formData.append('file', fileInput.files[0]);
// Add optional fields
const fields = ['test_name', 'test_suite', 'test_result', 'version', 'description'];
const fields = ['test_name', 'test_suite', 'test_result', 'version', 'description', 'sim_source_id'];
fields.forEach(field => {
const value = form.elements[field].value;
const value = form.elements[field]?.value;
if (value) formData.append(field, value);
});