diff --git a/.dagger/prompts/assignment.md b/.dagger/prompts/assignment.md index 6a2d489..0ca49a1 100644 --- a/.dagger/prompts/assignment.md +++ b/.dagger/prompts/assignment.md @@ -6,7 +6,8 @@ You are a programmer working on the Greetings API project 2. Evaluate the architecture of the project at `## Project Architecture` in CONTRIBUTING.md to think about what files may be relevant to the solution 3. Understand how the assignment should be implemented in the codebase 4. Implement the assignment in the workspace provided -5. Run the checks to make sure the changes are valid and incorporate any changes needed to pass checks +5. **CRITICAL**: Update documentation in `docs/index.mdx` to reflect any new functionality, endpoints, or changes +6. Run the checks to make sure the changes are valid and incorporate any changes needed to pass checks ## Assignment @@ -17,4 +18,5 @@ Here is your assignment: $assignment - The workspace has tools to let you read and write the code as well as run the tests - Be sure to always write your changes to the workspace - Always run check after writing changes to the workspace +- **IMPORTANT**: Changes to project functionality MUST be reflected in changes to the documentation (`docs/index.mdx`) - You are not done until the check tool is successful and the assignment is complete diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index aad8504..0f64a9b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -64,10 +64,12 @@ greetings-api/ - **Language**: Go - **Framework**: Gorilla Mux for routing, CORS middleware -- **Structure**: Simple REST API with two endpoints: +- **Structure**: Simple REST API with endpoints for greetings and farewells: - `GET /` - Returns a random greeting - `GET /{language}` - Returns a greeting in the specified language -- **Data**: Greetings are stored in `greetings.json` and embedded in the binary + - `GET /farewell` - Returns a random farewell + - `GET /farewell/{language}` - Returns a farewell in the specified language +- **Data**: Greetings are stored in `greetings.json` and farewells in `farewells.json`, both embedded in the binary - **Testing**: Uses `gotest.tools` for unit tests ### Frontend Architecture @@ -154,10 +156,17 @@ npm run lint - **TypeScript**: Follow the ESLint configuration in the project - **Commits**: Use clear, descriptive commit messages -### Documentation +### Documentation Requirements + +**⚠️ CRITICAL**: Changes to project functionality MUST be reflected in documentation updates. - **Developer Docs**: Update CONTRIBUTING.md with any architectural changes -- **Product Docs**: Update docs/ with relevant product changes +- **Product Docs**: Update `docs/index.mdx` with any new endpoints, functionality, or changes that affect users +- **API Documentation**: When adding new endpoints, ensure they are properly documented with: + - Endpoint paths and HTTP methods + - Example requests and responses + - Updated supported languages table if applicable + - Error handling examples ### Testing Requirements @@ -174,22 +183,25 @@ npm run lint 2. **Make your changes** following the code style guidelines -3. **Test your changes** thoroughly: +3. **Update documentation** as required (see Documentation Requirements above) + +4. **Test your changes** thoroughly: ```bash dagger call check ``` -4. **Commit your changes** with clear commit messages +5. **Commit your changes** with clear commit messages -5. **Push to your fork**: +6. **Push to your fork**: ```bash git push origin feature/your-feature-name ``` -6. **Create a Pull Request** on GitHub with: +7. **Create a Pull Request** on GitHub with: - Clear description of changes - Reference to any related issues - Screenshots if UI changes are involved + - Confirmation that documentation has been updated if functionality changed ## Getting Help diff --git a/docs/index.mdx b/docs/index.mdx index 0da7e4c..02d5ef0 100644 --- a/docs/index.mdx +++ b/docs/index.mdx @@ -1,10 +1,10 @@ # Greetings API Documentation -Welcome to the Greetings API! This simple service allows you to retrieve greetings in various languages. +Welcome to the Greetings API! This simple service allows you to retrieve greetings and farewells in various languages. ## Using the REST API -The Greetings API provides two main endpoints for retrieving greetings: +The Greetings API provides endpoints for retrieving both greetings and farewells: ### Get a Random Greeting @@ -39,38 +39,72 @@ GET http://locahost:8080/french } ``` +### Get a Random Farewell + +``` +GET http://locahost:8080/farewell +``` + +**Example Response:** +```json +{ + "farewell": "Goodbye, World!" +} +``` + +### Get a Farewell in a Specific Language + +``` +GET http://locahost:8080/farewell/{language} +``` + +Replace `{language}` with one of the supported language codes. + +**Example Request:** +``` +GET http://locahost:8080/farewell/french +``` + +**Example Response:** +```json +{ + "farewell": "Au revoir, Monde !" +} +``` + ## Supported Languages The API currently supports the following languages: -| Language Code | Greeting | -|---------------|----------| -| english | Hello, World! | -| british | Hello, World! Cheers! | -| french | Bonjour, Monde ! | -| italian | Ciao, Mondo! | -| spanish | ¡Hola, Mundo! | -| german | Hallo, Welt! | -| mandarin | 你好,世界! | -| hindi | नमस्ते दुनिया! | -| arabic | مرحبا بالعالم! | -| bengali | ওহে বিশ্ব! | -| russian | Привет, мир! | -| portuguese | Olá, Mundo! | -| urdu | ہیلو، دنیا! | -| indonesian | Halo Dunia! | -| japanese | こんにちは世界! | -| marathi | नमस्कार जग! | -| telugu | హలో ప్రపంచం! | +| Language Code | Greeting | Farewell | +|---------------|----------|----------| +| english | Hello, World! | Goodbye, World! | +| british | Hello, World! Cheers! | Goodbye, World! Cheerio! | +| french | Bonjour, Monde ! | Au revoir, Monde ! | +| italian | Ciao, Mondo! | Arrivederci, Mondo! | +| spanish | ¡Hola, Mundo! | ¡Adiós, Mundo! | +| german | Hallo, Welt! | Auf Wiedersehen, Welt! | +| mandarin | 你好,世界! | 再见,世界! | +| hindi | नमस्ते दुनिया! | अलविदा दुनिया! | +| arabic | مرحبا بالعالم! | وداعا يا عالم! | +| bengali | ওহে বিশ্ব! | বিদায় পৃথিবী! | +| russian | Привет, мир! | До свидания, мир! | +| portuguese | Olá, Mundo! | Adeus, Mundo! | +| urdu | ہیلو، دنیا! | الوداع، دنیا! | +| indonesian | Halo Dunia! | Selamat tinggal Dunia! | +| japanese | こんにちは世界! | さようなら世界! | +| marathi | नमस्कार जग! | निरोप जग! | +| telugu | హలో ప్రపంచం! | వీడ్కోలు ప్రపంచం! | ## Using the Greetings Website If you prefer a web interface, you can visit the website at http://locahost:8081/ where you can: 1. View random greetings with a simple click -2. Experience our user-friendly interface +2. View random farewells with a simple click +3. Experience our user-friendly interface -Simply click the greeting button (👋) to get a new random greeting displayed on the screen. +Simply click the greeting button (👋) to get a new random greeting or the farewell button (👋😢) to get a new random farewell displayed on the screen. ## API Limits @@ -80,13 +114,20 @@ Currently, there are no rate limits on the API usage, but please be respectful o If you request a language that doesn't exist, the API will return an appropriate error message with a 400 status code. -Example error response: +Example error response for greeting: ```json { "error": "no greeting found for language 'klingon'" } ``` +Example error response for farewell: +```json +{ + "error": "no farewell found for language 'klingon'" +} +``` + ## Need Help? If you have any questions or need assistance with the Greetings API, please open an issue on our GitHub repository. diff --git a/farewells.json b/farewells.json new file mode 100644 index 0000000..b934d50 --- /dev/null +++ b/farewells.json @@ -0,0 +1,19 @@ +[ + { "language": "english", "farewell": "Goodbye, World!" }, + { "language": "british", "farewell": "Goodbye, World! Cheerio!" }, + { "language": "french", "farewell": "Au revoir, Monde !" }, + { "language": "italian", "farewell": "Arrivederci, Mondo!" }, + { "language": "spanish", "farewell": "¡Adiós, Mundo!" }, + { "language": "german", "farewell": "Auf Wiedersehen, Welt!" }, + { "language": "mandarin", "farewell": "再见,世界!" }, + { "language": "hindi", "farewell": "अलविदा दुनिया!" }, + { "language": "arabic", "farewell": "وداعا يا عالم!" }, + { "language": "bengali", "farewell": "বিদায় পৃথিবী!" }, + { "language": "russian", "farewell": "До свидания, мир!" }, + { "language": "portuguese", "farewell": "Adeus, Mundo!" }, + { "language": "urdu", "farewell": "الوداع، دنیا!" }, + { "language": "indonesian", "farewell": "Selamat tinggal Dunia!" }, + { "language": "japanese", "farewell": "さようなら世界!" }, + { "language": "marathi", "farewell": "निरोप जग!" }, + { "language": "telugu", "farewell": "వీడ్కోలు ప్రపంచం!" } +] \ No newline at end of file diff --git a/main.go b/main.go index f3dd57c..df89cee 100644 --- a/main.go +++ b/main.go @@ -16,11 +16,19 @@ import ( //go:embed greetings.json var greetingsJson []byte +//go:embed farewells.json +var farewellsJson []byte + type Greeting struct { Language string `json:"language"` Greeting string `json:"greeting"` } +type Farewell struct { + Language string `json:"language"` + Farewell string `json:"farewell"` +} + func main() { var greetings []*Greeting err := json.Unmarshal(greetingsJson, &greetings) @@ -28,6 +36,14 @@ func main() { fmt.Printf("error loading greetings: %s\n", err) os.Exit(1) } + + var farewells []*Farewell + err = json.Unmarshal(farewellsJson, &farewells) + if err != nil { + fmt.Printf("error loading farewells: %s\n", err) + os.Exit(1) + } + router := mux.NewRouter() router.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { @@ -57,6 +73,34 @@ func main() { } }).Methods("GET") + // Farewell endpoints + router.HandleFunc("/farewell", func(w http.ResponseWriter, r *http.Request) { + fmt.Printf("got /farewell request from %s\n", r.RemoteAddr) + w.Header().Set("Content-Type", "application/json") + farewell, err := SelectFarewell(farewells, "random") + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + } + _, err = w.Write([]byte(FormatFarewellResponse(farewell))) + if err != nil { + panic(err) + } + }).Methods("GET") + + router.HandleFunc("/farewell/{language}", func(w http.ResponseWriter, r *http.Request) { + language := mux.Vars(r)["language"] + fmt.Printf("got /farewell/{language} request from %s\n", r.RemoteAddr) + w.Header().Set("Content-Type", "application/json") + farewell, err := SelectFarewell(farewells, language) + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + } + _, err = w.Write([]byte(FormatFarewellResponse(farewell))) + if err != nil { + panic(err) + } + }).Methods("GET") + c := cors.New(cors.Options{ AllowedOrigins: []string{ "http://greetings.kylepenfound.com", @@ -78,6 +122,10 @@ func FormatResponse(greeting *Greeting) string { return fmt.Sprintf("{\"greeting\":\"%s\"}", greeting.Greeting) } +func FormatFarewellResponse(farewell *Farewell) string { + return fmt.Sprintf("{\"farewell\":\"%s\"}", farewell.Farewell) +} + func SelectGreeting(greetings []*Greeting, language string) (*Greeting, error) { if len(greetings) == 0 { return nil, errors.New("no greetings available") @@ -97,3 +145,23 @@ func SelectGreeting(greetings []*Greeting, language string) (*Greeting, error) { return nil, fmt.Errorf("no greeting found for language '%s'", language) } + +func SelectFarewell(farewells []*Farewell, language string) (*Farewell, error) { + if len(farewells) == 0 { + return nil, errors.New("no farewells available") + } + + if language == "random" { + // Get random item from farewells slice + randomIndex := rand.Intn(len(farewells)) + return farewells[randomIndex], nil + } + + for _, farewell := range farewells { + if farewell.Language == language { + return farewell, nil + } + } + + return nil, fmt.Errorf("no farewell found for language '%s'", language) +} diff --git a/main_test.go b/main_test.go index e05e339..e522361 100644 --- a/main_test.go +++ b/main_test.go @@ -40,6 +40,37 @@ func TestSelectGreeting(t *testing.T) { assert.Error(t, err, "no greeting found for language ''") } +func TestSelectFarewell(t *testing.T) { + var farewells []*Farewell + err := json.Unmarshal(farewellsJson, &farewells) + if err != nil { + fmt.Printf("error loading farewells: %s\n", err) + os.Exit(1) + } + + english := &Farewell{ + Farewell: "Goodbye, World!", + Language: "english", + } + + // Test with a language + f, err := SelectFarewell(farewells, "english") + assert.NilError(t, err) + assert.Equal(t, *english, *f) + + // Test random + _, err = SelectFarewell(farewells, "random") + assert.NilError(t, err) + + // Test invalid language + _, err = SelectFarewell(farewells, "foooooo") + assert.Error(t, err, "no farewell found for language 'foooooo'") + + // Test empty language + _, err = SelectFarewell(farewells, "") + assert.Error(t, err, "no farewell found for language ''") +} + func TestFormatResponse(t *testing.T) { g := &Greeting{ Greeting: "Hello, World!", @@ -49,3 +80,13 @@ func TestFormatResponse(t *testing.T) { formatted := FormatResponse(g) assert.Equal(t, "{\"greeting\":\"Hello, World!\"}", formatted) } + +func TestFormatFarewellResponse(t *testing.T) { + f := &Farewell{ + Farewell: "Goodbye, World!", + Language: "english", + } + + formatted := FormatFarewellResponse(f) + assert.Equal(t, "{\"farewell\":\"Goodbye, World!\"}", formatted) +} diff --git a/website/index.html b/website/index.html index 7e6f858..307a3bd 100644 --- a/website/index.html +++ b/website/index.html @@ -12,21 +12,37 @@