feat(console,api): implement /console Admin Dashboard and Go backend full CRUD REST APIs
- Add comprehensive /console admin web UI for managing research projects, areas, members, publications, patents, lectures, and standards - Implement Admin token authentication middleware (RequireAdminToken) with Bearer token validation - Implement POST, PUT, DELETE REST API endpoints for all database entities across 5 domains - Add typed admin API client in refer_landing_page/lib/adminApi.ts with localStorage session persistence - Enhance E2E test runner to manage backend server lifecycle during automated tests - Pass all 12 quality gates cleanly with unanimous reviewer PASS verdicts
This commit is contained in:
@@ -48,6 +48,46 @@ func (r *PublicationsRepository) GetPublications(ctx context.Context, category s
|
||||
return pubs, rows.Err()
|
||||
}
|
||||
|
||||
func (r *PublicationsRepository) CreatePublication(ctx context.Context, p models.Publication) (int, error) {
|
||||
res, err := r.db.ExecContext(ctx, `
|
||||
INSERT INTO publications (category, title, authors, venue, volume, published_at, kci, doi, is_highlight)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
`, p.Category, p.Title, p.Authors, p.Venue, p.Volume, p.PublishedAt, p.KCI, p.DOI, p.IsHighlight)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("insert publication: %w", err)
|
||||
}
|
||||
id, err := res.LastInsertId()
|
||||
return int(id), err
|
||||
}
|
||||
|
||||
func (r *PublicationsRepository) UpdatePublication(ctx context.Context, id int, p models.Publication) error {
|
||||
res, err := r.db.ExecContext(ctx, `
|
||||
UPDATE publications
|
||||
SET category = ?, title = ?, authors = ?, venue = ?, volume = ?, published_at = ?, kci = ?, doi = ?, is_highlight = ?
|
||||
WHERE id = ?
|
||||
`, p.Category, p.Title, p.Authors, p.Venue, p.Volume, p.PublishedAt, p.KCI, p.DOI, p.IsHighlight, id)
|
||||
if err != nil {
|
||||
return fmt.Errorf("update publication: %w", err)
|
||||
}
|
||||
rows, err := res.RowsAffected()
|
||||
if err == nil && rows == 0 {
|
||||
return sql.ErrNoRows
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (r *PublicationsRepository) DeletePublication(ctx context.Context, id int) error {
|
||||
res, err := r.db.ExecContext(ctx, `DELETE FROM publications WHERE id = ?`, id)
|
||||
if err != nil {
|
||||
return fmt.Errorf("delete publication: %w", err)
|
||||
}
|
||||
rows, err := res.RowsAffected()
|
||||
if err == nil && rows == 0 {
|
||||
return sql.ErrNoRows
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (r *PublicationsRepository) GetHighlights(ctx context.Context) ([]models.Publication, error) {
|
||||
query := `
|
||||
SELECT id, category, title, authors, venue, volume, published_at, kci, doi, is_highlight, created_at
|
||||
@@ -100,3 +140,43 @@ func (r *PublicationsRepository) GetPatents(ctx context.Context) ([]models.Paten
|
||||
}
|
||||
return patents, rows.Err()
|
||||
}
|
||||
|
||||
func (r *PublicationsRepository) CreatePatent(ctx context.Context, p models.Patent) (int, error) {
|
||||
res, err := r.db.ExecContext(ctx, `
|
||||
INSERT INTO patents (title, inventors, application_no, application_at, registration_no, registration_at, country, published_at)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
||||
`, p.Title, p.Inventors, p.ApplicationNo, p.ApplicationAt, p.RegistrationNo, p.RegistrationAt, p.Country, p.PublishedAt)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("insert patent: %w", err)
|
||||
}
|
||||
id, err := res.LastInsertId()
|
||||
return int(id), err
|
||||
}
|
||||
|
||||
func (r *PublicationsRepository) UpdatePatent(ctx context.Context, id int, p models.Patent) error {
|
||||
res, err := r.db.ExecContext(ctx, `
|
||||
UPDATE patents
|
||||
SET title = ?, inventors = ?, application_no = ?, application_at = ?, registration_no = ?, registration_at = ?, country = ?, published_at = ?
|
||||
WHERE id = ?
|
||||
`, p.Title, p.Inventors, p.ApplicationNo, p.ApplicationAt, p.RegistrationNo, p.RegistrationAt, p.Country, p.PublishedAt, id)
|
||||
if err != nil {
|
||||
return fmt.Errorf("update patent: %w", err)
|
||||
}
|
||||
rows, err := res.RowsAffected()
|
||||
if err == nil && rows == 0 {
|
||||
return sql.ErrNoRows
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (r *PublicationsRepository) DeletePatent(ctx context.Context, id int) error {
|
||||
res, err := r.db.ExecContext(ctx, `DELETE FROM patents WHERE id = ?`, id)
|
||||
if err != nil {
|
||||
return fmt.Errorf("delete patent: %w", err)
|
||||
}
|
||||
rows, err := res.RowsAffected()
|
||||
if err == nil && rows == 0 {
|
||||
return sql.ErrNoRows
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user