working summary api
This commit is contained in:
parent
54016c0168
commit
02dcbcc507
|
@ -9,15 +9,17 @@ import (
|
|||
//TODO: this should match the ID and username for the user.
|
||||
type JWTClaim struct {
|
||||
Username string `json:"username"`
|
||||
UserId string `json:"user_id"`
|
||||
Email string `json:"email"`
|
||||
jwt.StandardClaims
|
||||
}
|
||||
|
||||
func GenerateJWT(encryptionKey string, username string) (tokenString string, err error) {
|
||||
func GenerateJWT(encryptionKey string, username string, userId string) (tokenString string, err error) {
|
||||
expirationTime := time.Now().Add(2 * time.Hour)
|
||||
claims := &JWTClaim{
|
||||
Username: username,
|
||||
Email: username,
|
||||
UserId: userId,
|
||||
StandardClaims: jwt.StandardClaims{
|
||||
ExpiresAt: expirationTime.Unix(),
|
||||
},
|
||||
|
|
|
@ -13,6 +13,8 @@ type DatabaseRepository interface {
|
|||
GetUserByEmail(context.Context, string) (*models.User, error)
|
||||
GetCurrentUser(context.Context) models.User
|
||||
|
||||
GetSummary(ctx context.Context) (*models.Summary, error)
|
||||
|
||||
UpsertResource(context.Context, models.ResourceFhir) error
|
||||
GetResource(context.Context, string) (*models.ResourceFhir, error)
|
||||
GetResourceBySourceId(context.Context, string, string) (*models.ResourceFhir, error)
|
||||
|
|
|
@ -109,6 +109,43 @@ func (sr *sqliteRepository) GetCurrentUser(ctx context.Context) models.User {
|
|||
return currentUser
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// User
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
func (sr *sqliteRepository) GetSummary(ctx context.Context) (*models.Summary, error) {
|
||||
|
||||
// we want a count of all resources for this user by type
|
||||
var resourceCountResults []map[string]interface{}
|
||||
|
||||
//group by resource type and return counts
|
||||
// SELECT source_resource_type as resource_type, COUNT(*) as count FROM resource_fhirs WHERE source_id = "53c1e930-63af-46c9-b760-8e83cbc1abd9" GROUP BY source_resource_type;
|
||||
result := sr.gormClient.WithContext(ctx).
|
||||
Model(models.ResourceFhir{}).
|
||||
Select("source_id, source_resource_type as resource_type, count(*) as count").
|
||||
Group("source_resource_type").
|
||||
Where(models.OriginBase{
|
||||
UserID: sr.GetCurrentUser(ctx).ID,
|
||||
}).
|
||||
Scan(&resourceCountResults)
|
||||
if result.Error != nil {
|
||||
return nil, result.Error
|
||||
}
|
||||
|
||||
// we want a list of all sources (when they were last updated)
|
||||
sources, err := sr.GetSources(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
summary := &models.Summary{
|
||||
Sources: sources,
|
||||
ResourceTypeCounts: resourceCountResults,
|
||||
}
|
||||
|
||||
return summary, nil
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Resource
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -248,9 +285,9 @@ func (sr *sqliteRepository) GetSourceSummary(ctx context.Context, sourceId strin
|
|||
//group by resource type and return counts
|
||||
// SELECT source_resource_type as resource_type, COUNT(*) as count FROM resource_fhirs WHERE source_id = "53c1e930-63af-46c9-b760-8e83cbc1abd9" GROUP BY source_resource_type;
|
||||
|
||||
var results []map[string]interface{}
|
||||
var resourceTypeCounts []map[string]interface{}
|
||||
|
||||
sr.gormClient.WithContext(ctx).
|
||||
result := sr.gormClient.WithContext(ctx).
|
||||
Model(models.ResourceFhir{}).
|
||||
Select("source_id, source_resource_type as resource_type, count(*) as count").
|
||||
Group("source_resource_type").
|
||||
|
@ -258,9 +295,13 @@ func (sr *sqliteRepository) GetSourceSummary(ctx context.Context, sourceId strin
|
|||
UserID: sr.GetCurrentUser(ctx).ID,
|
||||
SourceID: sourceUUID,
|
||||
}).
|
||||
Scan(&results)
|
||||
Scan(&resourceTypeCounts)
|
||||
|
||||
sourceSummary.ResourceTypeCounts = results
|
||||
if result.Error != nil {
|
||||
return nil, result.Error
|
||||
}
|
||||
|
||||
sourceSummary.ResourceTypeCounts = resourceTypeCounts
|
||||
|
||||
return sourceSummary, nil
|
||||
}
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
package models
|
||||
|
||||
type Summary struct {
|
||||
Sources []Source `json:"sources,omitempty"`
|
||||
ResourceTypeCounts []map[string]interface{} `json:"resource_type_counts,omitempty"`
|
||||
}
|
|
@ -26,7 +26,7 @@ func AuthSignup(c *gin.Context) {
|
|||
}
|
||||
|
||||
// return JWT
|
||||
tokenString, err := auth.GenerateJWT(appConfig.GetString("web.jwt.encryptionkey"), user.Username)
|
||||
tokenString, err := auth.GenerateJWT(appConfig.GetString("web.jwt.encryptionkey"), user.Username, user.ID.String())
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"success": false})
|
||||
return
|
||||
|
@ -58,7 +58,7 @@ func AuthSignin(c *gin.Context) {
|
|||
}
|
||||
|
||||
// return JWT
|
||||
tokenString, err := auth.GenerateJWT(appConfig.GetString("web.jwt.encryptionkey"), user.Username)
|
||||
tokenString, err := auth.GenerateJWT(appConfig.GetString("web.jwt.encryptionkey"), user.Username, user.ID.String())
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"success": false, "error": "an error occurred generating JWT token"})
|
||||
return
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
package handler
|
||||
|
||||
import (
|
||||
"github.com/fastenhealth/fastenhealth-onprem/backend/pkg/database"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/sirupsen/logrus"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func GetSummary(c *gin.Context) {
|
||||
logger := c.MustGet("LOGGER").(*logrus.Entry)
|
||||
databaseRepo := c.MustGet("REPOSITORY").(database.DatabaseRepository)
|
||||
|
||||
summary, err := databaseRepo.GetSummary(c)
|
||||
if err != nil {
|
||||
logger.Errorln("An error occurred while retrieving summary", err)
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"success": false})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, gin.H{"success": true, "data": summary})
|
||||
}
|
|
@ -40,6 +40,7 @@ func RequireAuth() gin.HandlerFunc {
|
|||
//todo, is this shared between all sessions??
|
||||
c.Set("AUTH_TOKEN", tokenString)
|
||||
c.Set("AUTH_USERNAME", claim.Username)
|
||||
c.Set("AUTH_USERID", claim.UserId)
|
||||
|
||||
c.Next()
|
||||
}
|
||||
|
|
|
@ -45,6 +45,8 @@ func (ae *AppEngine) Setup(logger *logrus.Entry) *gin.Engine {
|
|||
|
||||
secure := api.Group("/secure").Use(middleware.RequireAuth())
|
||||
{
|
||||
secure.GET("/summary", handler.GetSummary)
|
||||
|
||||
secure.POST("/source", handler.CreateSource)
|
||||
secure.POST("/source/manual", handler.CreateManualSource)
|
||||
secure.GET("/source", handler.ListSource)
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
import {Source} from './source';
|
||||
import {ResourceTypeCounts} from './source-summary';
|
||||
|
||||
export class Summary {
|
||||
sources: Source[]
|
||||
resource_type_counts: ResourceTypeCounts[]
|
||||
}
|
|
@ -55,7 +55,7 @@
|
|||
</div>
|
||||
<div>
|
||||
<label>Encounters</label>
|
||||
<h4>41</h4>
|
||||
<h4>{{encounterCount}}</h4>
|
||||
</div>
|
||||
</div><!-- col -->
|
||||
<div class="col-6 d-sm-flex align-items-center">
|
||||
|
@ -64,7 +64,7 @@
|
|||
</div>
|
||||
<div>
|
||||
<label>All Records</label>
|
||||
<h4>9,065</h4>
|
||||
<h4>{{recordsCount}}</h4>
|
||||
</div>
|
||||
</div><!-- col -->
|
||||
</div><!-- card-body -->
|
||||
|
@ -84,7 +84,7 @@
|
|||
</div>
|
||||
<div>
|
||||
<label>Sources</label>
|
||||
<h4>30</h4>
|
||||
<h4>{{sources.length}}</h4>
|
||||
</div>
|
||||
</div>
|
||||
</div><!-- col -->
|
||||
|
|
|
@ -3,6 +3,8 @@ import {FastenApiService} from '../../services/fasten-api.service';
|
|||
import {LighthouseSource} from '../../models/lighthouse/lighthouse-source';
|
||||
import {Source} from '../../models/fasten/source';
|
||||
import {Router} from '@angular/router';
|
||||
import {Summary} from '../../models/fasten/summary';
|
||||
import {ResourceTypeCounts} from '../../models/fasten/source-summary';
|
||||
|
||||
@Component({
|
||||
selector: 'app-dashboard',
|
||||
|
@ -12,15 +14,25 @@ import {Router} from '@angular/router';
|
|||
export class DashboardComponent implements OnInit {
|
||||
|
||||
sources: Source[] = []
|
||||
encounterCount: number = 0
|
||||
recordsCount: number = 0
|
||||
|
||||
constructor(private fastenApi: FastenApiService, private router: Router) { }
|
||||
|
||||
ngOnInit() {
|
||||
|
||||
this.fastenApi.getSources()
|
||||
.subscribe( (sourcesList) => {
|
||||
console.log(sourcesList);
|
||||
this.sources = sourcesList
|
||||
this.fastenApi.getSummary()
|
||||
.subscribe( (summary) => {
|
||||
console.log(summary);
|
||||
this.sources = summary.sources
|
||||
|
||||
//calculate the number of records
|
||||
summary.resource_type_counts.forEach((resourceTypeInfo) => {
|
||||
this.recordsCount += resourceTypeInfo.count
|
||||
if(resourceTypeInfo.resource_type == "Encounter"){
|
||||
this.encounterCount = resourceTypeInfo.count
|
||||
}
|
||||
})
|
||||
})
|
||||
// this.fastenApi.getResources('Patient')
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ import {Source} from '../models/fasten/source';
|
|||
import {User} from '../models/fasten/user';
|
||||
import {ResourceFhir} from '../models/fasten/resource_fhir';
|
||||
import {SourceSummary} from '../models/fasten/source-summary';
|
||||
import {Summary} from '../models/fasten/summary';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
|
@ -66,6 +67,15 @@ export class FastenApiService {
|
|||
/*
|
||||
SECURE ENDPOINTS
|
||||
*/
|
||||
getSummary(): Observable<Summary> {
|
||||
return this._httpClient.get<any>(`${this.getBasePath()}/api/secure/summary`, )
|
||||
.pipe(
|
||||
map((response: ResponseWrapper) => {
|
||||
console.log("Summary RESPONSE", response)
|
||||
return response.data as Summary
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
createSource(source: Source): Observable<Source> {
|
||||
return this._httpClient.post<any>(`${this.getBasePath()}/api/secure/source`, source)
|
||||
|
|
Loading…
Reference in New Issue