Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion cosmo-router/graph.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,7 @@ subgraphs:
file: ../subgraphs/products/schema.graphql
- plugin:
version: 0.0.1
path: plugins/users
path: plugins/users
- plugin:
version: 0.0.1
path: plugins/courses
16 changes: 13 additions & 3 deletions cosmo-router/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,19 @@
"type": "module",
"scripts": {
"compose": "wgc router compose -i graph.yaml -o config.json",
"build": "wgc router plugin build plugins/users --debug && npm run compose",
"test": "wgc router plugin test plugins/users",
"generate": "wgc router plugin build plugins/users --generate-only",

"build:users": "wgc router plugin build plugins/users --debug",
"build:courses": "wgc router plugin build plugins/courses --debug",
"build": "npm run build:users && npm run build:courses && npm run compose",

"test:users": "wgc router plugin test plugins/users",
"test:courses": "wgc router plugin test plugins/courses",
"test": "npm run test:users && npm run test:courses",

"generate:users": "wgc router plugin build plugins/users --generate-only",
"generate:courses": "wgc router plugin build plugins/courses --generate-only",
"generate": "npm run generate:users && npm run generate:courses",

"postinstall": "rm -rf release && wgc router download-binary -o release && chmod +x release/router",
"start": "./release/router"
},
Expand Down
2 changes: 2 additions & 0 deletions cosmo-router/plugins/courses/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Ignore the binary files
bin/
19 changes: 19 additions & 0 deletions cosmo-router/plugins/courses/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@

.PHONY: build test generate install-wgc

install-wgc:
@which wgc > /dev/null 2>&1 || npm install -g wgc@latest

make: build

test: install-wgc
wgc router plugin test .

generate: install-wgc
wgc router plugin generate .

publish: generate
wgc router plugin publish .

build: install-wgc
wgc router plugin build . --debug
120 changes: 120 additions & 0 deletions cosmo-router/plugins/courses/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
# Courses Plugin

A Cosmo Router plugin for course management and enrollment. This plugin provides a GraphQL API for managing courses, instructors, and student enrollments using gRPC service implementation.

## Features

- Course creation and management
- Instructor course assignments
- In-memory data storage with mock data

## Testing

The tests validate all functionality of the plugin including:

- Course querying (all courses and by ID)
- User lookup by ID (instructors and students)
- Course creation
- Student enrollment in courses

### Running Tests

```bash
cd cosmo-router/plugins/courses
make test
```

## Directory Structure

```
courses/
├── bin/ # Compiled plugin binaries
├── generated/ # Auto-generated gRPC code from schema
│ ├── service.pb.js
│ ├── service_grpc_pb.js
│ └── service.proto
├── src/ # Source code
│ ├── plugin.ts # Plugin implementation
│ ├── plugin.test.ts # Integration tests
│ ├── plugin-server.ts # gRPC server setup
│ └── schema.graphql # GraphQL schema definition
└── package.json # Dependencies
```

## GraphQL API

### Queries

- `courses`: List all courses
- `course(id: ID!)`: Get a course by ID

### Mutations

- `createCourse(input: CourseInput!)`: Create a new course
- `enrollUser(userId: ID!, courseId: ID!)`: Enroll a user in a course


## Example GraphQL Operations

```graphql
# Get all courses
query {
courses {
id
title
description
instructor {
id
}
durationHours
published
}
}

# Get a specific course
query {
course(id: "course-1") {
id
title
description
instructor {
id
}
durationHours
published
}
}

# Create a new course
mutation {
createCourse(input: {
title: "Advanced GraphQL"
description: "Master GraphQL concepts"
instructorId: "1"
durationHours: 30
published: true
}) {
id
title
description
instructor {
id
}
}
}

# Enroll a user in a course
mutation {
enrollUser(userId: "user-1", courseId: "course-1") {
id
user {
id
}
course {
id
title
}
progress
}
}
```
236 changes: 236 additions & 0 deletions cosmo-router/plugins/courses/bun.lock

Large diffs are not rendered by default.

217 changes: 217 additions & 0 deletions cosmo-router/plugins/courses/generated/mapping.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,217 @@
{
"version": 1,
"service": "CoursesService",
"operationMappings": [
{
"type": "OPERATION_TYPE_QUERY",
"original": "courses",
"mapped": "QueryCourses",
"request": "QueryCoursesRequest",
"response": "QueryCoursesResponse"
},
{
"type": "OPERATION_TYPE_QUERY",
"original": "course",
"mapped": "QueryCourse",
"request": "QueryCourseRequest",
"response": "QueryCourseResponse"
},
{
"type": "OPERATION_TYPE_MUTATION",
"original": "createCourse",
"mapped": "MutationCreateCourse",
"request": "MutationCreateCourseRequest",
"response": "MutationCreateCourseResponse"
},
{
"type": "OPERATION_TYPE_MUTATION",
"original": "enrollUser",
"mapped": "MutationEnrollUser",
"request": "MutationEnrollUserRequest",
"response": "MutationEnrollUserResponse"
}
],
"entityMappings": [
{
"typeName": "User",
"kind": "entity",
"key": "id",
"rpc": "LookupUserById",
"request": "LookupUserByIdRequest",
"response": "LookupUserByIdResponse"
}
],
"typeFieldMappings": [
{
"type": "Query",
"fieldMappings": [
{
"original": "courses",
"mapped": "courses",
"argumentMappings": []
},
{
"original": "course",
"mapped": "course",
"argumentMappings": [
{
"original": "id",
"mapped": "id"
}
]
}
]
},
{
"type": "Mutation",
"fieldMappings": [
{
"original": "createCourse",
"mapped": "create_course",
"argumentMappings": [
{
"original": "input",
"mapped": "input"
}
]
},
{
"original": "enrollUser",
"mapped": "enroll_user",
"argumentMappings": [
{
"original": "userId",
"mapped": "user_id"
},
{
"original": "courseId",
"mapped": "course_id"
}
]
}
]
},
{
"type": "User",
"fieldMappings": [
{
"original": "id",
"mapped": "id",
"argumentMappings": []
},
{
"original": "instructorCourses",
"mapped": "instructor_courses",
"argumentMappings": []
},
{
"original": "enrollments",
"mapped": "enrollments",
"argumentMappings": []
}
]
},
{
"type": "Course",
"fieldMappings": [
{
"original": "id",
"mapped": "id",
"argumentMappings": []
},
{
"original": "title",
"mapped": "title",
"argumentMappings": []
},
{
"original": "description",
"mapped": "description",
"argumentMappings": []
},
{
"original": "instructor",
"mapped": "instructor",
"argumentMappings": []
},
{
"original": "durationHours",
"mapped": "duration_hours",
"argumentMappings": []
},
{
"original": "published",
"mapped": "published",
"argumentMappings": []
},
{
"original": "enrollments",
"mapped": "enrollments",
"argumentMappings": []
}
]
},
{
"type": "Enrollment",
"fieldMappings": [
{
"original": "id",
"mapped": "id",
"argumentMappings": []
},
{
"original": "user",
"mapped": "user",
"argumentMappings": []
},
{
"original": "course",
"mapped": "course",
"argumentMappings": []
},
{
"original": "progress",
"mapped": "progress",
"argumentMappings": []
},
{
"original": "enrolledAt",
"mapped": "enrolled_at",
"argumentMappings": []
}
]
},
{
"type": "CourseInput",
"fieldMappings": [
{
"original": "title",
"mapped": "title",
"argumentMappings": []
},
{
"original": "description",
"mapped": "description",
"argumentMappings": []
},
{
"original": "instructorId",
"mapped": "instructor_id",
"argumentMappings": []
},
{
"original": "durationHours",
"mapped": "duration_hours",
"argumentMappings": []
},
{
"original": "published",
"mapped": "published",
"argumentMappings": []
}
]
}
],
"enumMappings": [],
"resolveMappings": []
}
Loading