add_full_bottle_to_wishlist
ChatGPTUse this when the user wants the full bottle of a decant they own — they liked the sample enough to buy it. Adds that fragrance to their wishlist as a Full Bottle; the decant stays in the collection, and nothing is added if the full bottle is already on the wishlist.
add_many_to_collection
ChatGPTUse this when the user gives a list of fragrances they own — a spreadsheet, a CSV, a pasted inventory, or several named in one message — and add them in one call instead of one add_to_collection call per row. Each row takes the same fields as add_to_collection, with the user's name and house verbatim; no search_fragrances per row is needed, and confirm the import once up front rather than per row. At most 50 rows per call — split a longer list across calls. By default a row whose name and house match a bottle or decant the user already has (active or archived, and including an earlier row of the same call) is skipped and the existing id reported, so a re-run cannot double the collection; set skipOwned to false only when the user deliberately owns a second copy. Rows are independent: one that fails is reported at its index and the rest still land, so read the per-row results and never re-send a row that came back with an id. If Fraghab's catalog has no picture for a fragrance, Fraghab looks one up by name and house on a public perfume reference site and retailer sites; nothing about the user is sent.
add_many_to_wishlist
ChatGPTUse this when the user names several fragrances they want to buy, and put them on the buy queue in one call instead of one add_to_wishlist call each. Each row takes the same fields as add_to_wishlist. At most 50 rows per call. A row whose name and house match an active wishlist item — including an earlier row of the same call — is reported as a duplicate with the existing id and nothing is created, so a re-run is safe. Rows are independent: one that fails is reported at its index and the rest still land. If Fraghab's catalog has no picture for a fragrance, Fraghab looks one up by name and house on a public perfume reference site and retailer sites; nothing about the user is sent.
add_to_collection
ChatGPTAdd a fragrance the user owns to their collection, as a full bottle or a decant. Resolve the name and house with search_fragrances first so the entry matches the catalog. Set only what you actually know — an unset field is honest, a guessed one is data the user has to go and correct. A rating is per fragrance: a new entry with no rating takes the one the user's other bottle or decant of the same scent carries, and a rating on a new entry fills any unrated copy, never overwriting a rated one. For a list of several fragrances — a spreadsheet, a CSV, a pasted inventory — use add_many_to_collection instead of calling this once per row. If Fraghab's catalog has no picture for a fragrance, Fraghab looks one up by name and house on a public perfume reference site and retailer sites; nothing about the user is sent.
add_to_wishlist
ChatGPTPut a fragrance on the user's buy queue. If an active wishlist item with the same name and house already exists, that one is returned rather than a duplicate created. For a list of several, use add_many_to_wishlist. If Fraghab's catalog has no picture for a fragrance, Fraghab looks one up by name and house on a public perfume reference site and retailer sites; nothing about the user is sent.
bulk_update_collection
ChatGPTSet a single field to the same value across many entries at once — for example tagging a dozen bottles as Winter. An empty value clears the field. Season and occasion REPLACE the whole list on each entry rather than adding to it, so read the entries first if the user means to add a tag.
create_combo
ChatGPTSave a layering combo — two or more fragrances the user wears together. Take the ids from list_collection. Optionally record where each one goes and how many sprays.
get_collection_item
ChatGPTUse this when the user asks about one bottle or decant in depth — its notes and note pyramid, performance, price paid, remaining ml, how often and when it has been worn, cost per wear, which shelves it sits on, whether it is running low. list_collection gives the summary row; this gives everything the app's own detail page shows. Take the id from list_collection.
hunt_wishlist_price
ChatGPTSearch retailers for the best current price on something already on this user's wishlist, and return the cheapest offer with the retailer selling it. Name the fragrance, or pass the wishlistId that add_to_wishlist returned. The fresh result replaces the offers stored from any earlier hunt. It also gives the item a product photo if it doesn't have one yet. Each hunt spends one of the account's limited daily price scans, so call it when the user asks about price or where to buy — not automatically after every add.
list_collection
ChatGPTList the fragrances this user owns — full bottles and decants — with remaining ml, rating, wear count and the date each was last worn. The ids it returns are what every other tool takes.
list_combos
ChatGPTList the user's layering combos — the fragrance pairings they have saved — with what is in each, how often it has been worn, and when it was last worn.
list_shelves
ChatGPTList the user's shelves — the way they group bottles — with what is on each one.
list_wearings
ChatGPTUse this to read what the user wore and when — last week, a date range, a single day — newest first, with the occasion, their note, the spray count per fragrance, and the combo it came from if any. Use it for questions like 'what did I wear on Friday', 'how often have I worn X this month' or 'what have I not worn lately' (combine with list_collection's lastWorn for the latter). Page with the cursor it returns. To change a wearing, use update_wearing with the id.
list_wishlist
ChatGPTUse this to see the user's buy queue: every active wishlist item with its priority, the size and price they noted, their target price, and the best offer the last retailer scan found (price, shop, size, when). Read it before hunt_wishlist_price so you spend a scan only on an item that has none or a stale one, and take wishlist ids from here. Set includeBought to also list what they already bought.
log_combo_wearing
ChatGPTRecord that the user wore a whole saved combo on a day. Logs one wearing covering every fragrance in it and deducts each one's sprays from its remaining ml, using the combo's own spray map where it has one.
log_wearing
ChatGPTRecord that the user wore something from their collection on a given day. Deducts the sprayed ml from that bottle's remaining amount. Take the id from list_collection. For a layering combo use log_combo_wearing instead.
manage_shelf
ChatGPTCreate a shelf, or rename one / change its theme. Give shelfId to edit an existing shelf, or leave it out to create a new one. Renaming or re-theming replaces the old name or theme, which is not kept. Shelves are not deleted from here.
move_to_wishlist
ChatGPTThe user got rid of a bottle but still wants it tracked — sold it, used it up, or decided to rebuy later. Archives the collection entry, keeping every field, and puts it on the wishlist. Nothing is deleted or overwritten; set_collection_flags with archived false brings the bottle back unchanged.
plan_trip_packing
ChatGPTUse this when the user is travelling and asks what to bring: give the destination and dates and Fraghab builds a day-by-day packing list from their own collection against the forecast there — one pick per day with alternatives, a small set of bottles overall, and notes on travel-friendly sizes. Pass tripType for the occasion (Travel, Wedding, Beach…), bottleLimit to cap how many bottles they will carry, and mustPack for entries that go regardless. Trips are at most 14 days. It spends one of the user's daily planner runs, so call it once per trip and not to re-ask the same question; a repeat can differ.
promote_decant
ChatGPTThe user bought a full bottle of something they had as a decant. Creates the full-bottle entry from the decant's details, with its own copy of the artwork, and closes any full-bottle wishlist entry for the same scent. If the user had archived a bottle of it, that bottle is restored instead of duplicated. Pass bottleSize and pricePaid when the user says them — they describe the bottle, never the decant. By default the decant is left in the collection; set retireDecant to true only when the user says they are done with the decant, which archives it rather than deleting it. Restoring an archived bottle writes the bottle size, remaining ml and price given here over the values it had, and the old values are not kept.
promote_wishlist
ChatGPTThe user bought something off their wishlist. Moves it into the collection — restoring the original entry if this item came from one — and records what they paid. Restoring writes the price paid over the entry's previous price, which is not kept.
search_fragrances
ChatGPTSearch Fraghab's fragrance catalog and the wider community's entries by name or house. Returns matches with their house, concentration, notes and accords, and flags the ones already in this user's collection. Use this to resolve a fragrance before adding it.
set_collection_flags
ChatGPTSet the standalone flags on a collection entry: whether it is a favourite, whether it is archived, and a decant's verdict. Setting or clearing a verdict replaces the previous one, which is not kept. Archiving hides an entry from the collection without deleting it — it is not deleting; when the user asks to delete something, tell them that is done in the Fraghab app. Give only the flags being changed.
set_shelf_members
ChatGPTAdd bottles to a shelf or take them off it. Only bottles can sit on a shelf. Taking a bottle off a shelf deletes that membership and the date it was added to the shelf; the bottle itself stays in the collection.
submit_wearing_feedback
ChatGPTRecord how a fragrance actually performed on a day the user wore it — a thumbs up or down plus optional tags. This is what teaches the app's recommendations. Feedback on the same item again replaces the earlier sentiment, tags and mood, which are not kept.
suggest_wearing
ChatGPTUse this when the user asks what to wear — today, tonight, for an occasion, in a mood — and let Fraghab's own engine rank their collection: weather at their saved location, season, the occasion and mood you pass, what they have worn lately and how it performed, their ratings and their own learned preferences. Returns the daily pick, the top-ranked entries each with the reasons it scored, and any layering combos that fit. Pass the user's IANA timezone so 'today' is their today. Do not call it to answer general fragrance questions; it ranks only what the user owns. If the user has never logged a wearing it says so — suggestions need at least one.
update_collection_item
ChatGPTChange fields on a bottle or decant the user already owns — rating, notes, seasons, occasions, performance, remaining ml, price, the note pyramid, and so on. Send only the fields being changed; everything else is preserved. Setting a field to null clears it, which cannot be undone, so confirm before clearing something the user did not ask you to. A changed rating also updates the user's other bottles and decants of the same fragrance (a rating is per fragrance); clearing a rating never spreads. To change different fields on several entries in one step, use update_many_collection_items; to set one field to the same value across many, use bulk_update_collection.
update_combo
ChatGPTChange a saved combo. Name, description, rating and spray map keep their stored values unless you send them. The list of fragrances is REPLACED: read it back with list_combos first and send the full membership, or anything you leave out is dropped from the combo.
update_many_collection_items
ChatGPTUse this when several bottles or decants each need their own changes — different ratings, notes, seasons, prices, remaining ml — and make them in one call instead of one update_collection_item call each. Each row takes an id (and kind) plus the same fields as update_collection_item; send only the fields being changed on that row, and everything else on it is preserved, because each row is read first and merged. At most 50 rows per call. Setting a field to null clears it, which cannot be undone, so confirm before clearing anything the user did not ask for. Rows are independent: one that fails — an id that is not in this collection, say — is reported at its index and the rest still apply. For the SAME value on one field across many entries, bulk_update_collection is the smaller call.
update_wearing
ChatGPTFix a wearing that was logged wrong — its date, occasion, notes, or which fragrances it covered. Only the fields you name change; the rest are kept. Naming fragrances or decantIds REPLACES the wearing's item list, and the ml deducted for items taken off is returned to their bottles. The previous values are not kept, so the earlier version of the wearing cannot be restored.